代码之家  ›  专栏  ›  技术社区  ›  Dervin Thunk

C与WCALC:精度问题?

  •  0
  • Dervin Thunk  · 技术社区  · 15 年前

    考虑以下C代码:

      int c=((0xa3>>6)&0x1f)|0xc0;
      printf("%d\n",c);
    

    它正确地打印出194年( 0xc2 )。如果我写同样的东西 wcalc ,结果是195,或 0xc3 . 这是某种精度误差吗?这是预期行为吗? floor ceiling 函数不工作…或者,更具体地说, 地板 适用于0xA3,但不适用于,例如 0xa1 反之亦然。

    感谢您的帮助。谢谢。

    4 回复  |  直到 15 年前
        1
  •  2
  •   Martin B    15 年前

    实际上,wcalc处理 x >> y 不是整数位移位运算符(只从右侧删除移位的位),而是x的浮点除以2^y。因此:

    Enter an expression to evaluate, q to quit, or ? for help:
    -> 0xa3>>6
     = 2.54688
    

    这就解释了与C版本的区别,其中 0xa3 >> 6 仅仅是2。

        2
  •  3
  •   paxdiablo    15 年前

    为什么你问而不是测试?打破它。你从下面得到了什么?

    0xa3>>6
    (0xa3>>6)&0x1f
    ((0xa3>>6)&0x1f)|0xc0
    
    Enter an expression to evaluate, q to quit, or ? for help:
    -> ((0xa3>>6)&0x1f)|0xc0
     = 195
    -> 0xa3>>6
     = 2.54688
    -> (0xa3>>6)&0x1f
     = 3
    -> ((0xa3>>6)&0x1f)|0xc0
     = 195
    -> 
    

    看到那条线 "= 2.54688" . 你觉得对吗?根据我的计算, 0xa3>>6 应该给你2个,什么时候 and 埃德 0x1f 仍然 2岁。

    如果你试试下面的,你会看到的 >> 给出整数结果:

    Enter an expression to evaluate, q to quit, or ? for help:
    -> 0xa3
     = 163
    -> 0xa3>>1
     = 81.5
    -> 0xa3>>2
     = 40.75
    -> 
    
        3
  •  2
  •   user178010    15 年前

    我是wcalc的作者;您必须使用2.3.1版(这几乎已经过时一年了)。

    您看到的原因是,wcalc在内部使用来自mpfr库的任意精度浮点数,因此,用于将移位作为一个除法来执行(因此可以处理类似1.5>>6的事情)。版本2.4(2008年10月发布)处理整数位移位略有不同,以产生类似C的结果(如您所预期的)。

    值得一提的是,另一种命令行计算器是BC(在我看来,它更老,但使用起来更痛苦,而且没有那么多功能)。

        4
  •  1
  •   Andy Ross    15 年前

    这是一个整数运算,不涉及浮点精度问题。正确的答案是准确的,正如您已经知道的,示例代码正确地报告了正确的答案。这听起来像是“wcalc”(一个我不知道的工具)中的一个bug。