当前位置: 首页 > 知识库问答 >
问题:

我应该对浮点数使用位操作吗

籍辰沛
2023-03-14

我正在写一个算法,舍入一个浮点数。输入将是64位IEEE754双类型数,非常接近X.5,其中X是小于32的整数。我想到的第一个解决方案是使用位掩码,掩码掉那些最低有效位,因为它们代表2^-n的非常小的分数。(给定指数不大)。

但是问题是我应该这样做吗?有没有其他方法来完成同样的事情?我觉得在浮点上使用比特操作非常有争议。谢谢!

顺便说一下,我用的语言是C。

编辑:谢谢你们的评论。我很感激!假设我有一个浮点数,可以是1.4999999...或者21.50000012......我想把它四舍五入到1.5或21.5。我的目标是把任何数字四舍五入到最接近X.5的形式,因为它可以存储在IEEE754浮点数中。

共有3个答案

秦锐
2023-03-14

您想将x舍入到形式d.5的最近值。对于您编写的属号:

round(x+0.5)-0.5

对于接近d.5、距离小于0.25的数字,您可以使用Pascal的产品:

round(2*x)*0.5
滕弘新
2023-03-14

您可以使用任何函数轮()楼()ceil()rint()近字节()trunc()。所有函数都在不同的模式下进行舍入,并且都是标准的C99。您唯一需要做的就是通过指定-lm作为编译器标志来链接标准的数学库。

至于试图实现逐位舍入操作,我将远离这一点:a)它将比使用上述功能慢得多(它们通常在可能的情况下使用硬件设施),b)它正在重新发明轮子,有很多潜在的bug,c)较新的c标准不喜欢对浮点类型进行位操作:它们使用所谓的严格别名规则,不允许将double*强制转换为uint64.。您需要通过强制转换为无符号字符*并逐字节操作IEEE数字来执行位操作,或者必须使用memcpy()将位表示从double变量复制到uint64_t中,然后再复制回来。以标准化功能和硬件支持的形式提供的东西会带来很多麻烦。

葛勇锐
2023-03-14

如果您的编译器保证您使用的是IEEE 754浮点,我建议您按照本文中描述的方法进行取整:添加,然后立即减去一个大常量,以便在ULP为0.5的浮点数二进制中发送值。你找不到任何更快的方法,也不涉及任何比特操作。

对于IEEE 754双精度,将0到32之间的数字舍入到最接近的停止单元的适当常数是2251799813685248.0

总结:使用x=x2251799813685248.0-2251799813685248.0

 类似资料:
  • 众所周知,除法比乘法需要更多的时钟周期来计算。(请参阅此处的讨论:浮点除法与浮点乘法。) 我已经在我的C代码中使用了< code>x * 0.5而不是< code>x / 2和< code>x * 0.125而不是< code>x / 8,但是我想知道我应该这样做到什么程度。 对于倒置时重复出现的小数(即是重复出现的十进制),我使用除法而不是乘法(例如而不是)。 我的问题是:在迭代次数相当大的循环

  • 问题内容: 这仅在用户输入时有效,但是即使他们输入,我希望它也能正常工作,但在用户输入时无效。 因此,用户应该能够输入和,但不能输入。 我该怎么办? 问题答案: 使用正则表达式。

  • 我知道浮点值的实现和限制——我已经阅读了你可能会将我链接到的论文——但是我不知道我应该为浮点值使用什么范围。 我想在一个实的、有限的范围内表示一个值。概念上,-1比1。我可以只使用浮点值-1到1,但我是在浪费尾数位吗? 有一个问题,但并没有确切的答案。

  • 如果我想写从float到double的转换方法。 有没有可能两者会给出不同的结果? 如果我不关心平台一致性,我应该使用哪个版本? 如果我需要它在不同的平台上保持一致,该怎么办? 或: JLS 5.1。2: 从float到double的非strictfp加宽原语转换可能会丢失有关转换值的总体大小的信息。 为什么这种转换会丢失信息?

  • 问题内容: 在我的服务器应用程序中,我正在从Java应用程序连接到受Kerberos保护的Hadoop群集。我正在使用HDFS文件系统,Oozie,Hive等各种组件。在应用程序启动时,我确实打电话给 这将返回我的实例,并在应用程序生存期内保留它。当执行特权操作时,我使用启动它们。 这可以正常工作,但我想知道是否以及何时更新kerberos票?我发现了一种似乎在快要到期时都会进行票证更新的方法。我

  • 我最近开始学习Docker,知道它只需要一个简单的命令就可以在容器中创建和运行Ubuntu。 我还知道docker-machine使用VirtualBox以非常得心应手的方式创建Linux OS。 那么它们之间有什么区别呢?