c - 在 C89 中,如何将 double 浮点截断并拆分为两个 32 位字?

标签 c c99 c89 ansi-c

当以 C99 为目标时,我可以使用以下代码将 double 值截断并拆分为两个 32 位整数:

#include <stdint.h>

void split(double d, unsigned long *most_significant_word, unsigned long *least_significant_word)
{
   uint64_t i = (uint64_t)d;
   *most_significant_word = i >> 32;
   *least_significant_word = i & 0xffffffff;
}

然而,C89 似乎没有定义 64 位整数类型,所以我无法使用编译器来执行截断。即使不需要截断(该值已经表示一个整数),我也不能使用像 &>>> 这样的位运算符,因为它们不适用于 值。

那么,上面的 split() 函数如何在纯 C89 中实现(因此不依赖 64 位整数),返回组成 53- 的 21/32 位字位整数存储在 double 值中?

最佳答案

忽略符号(与原始代码一样)它应该像这样简单:

void split(double d, unsigned long *most_significant_word, unsigned long *least_significant_word)
{
   *most_significant_word = d/4294967296.; // d>>32 in double
   *least_significant_word = fmod(d, 4294967296.);
}

要考虑负数,对绝对值进行运算,然后计算补码:

void split(double d, unsigned long *most_significant_word, unsigned long *least_significant_word)
{
   double dabs = d < 0 ? -d : d;
   *most_significant_word = dabs/4294967296.;
   *least_significant_word = fmod(dabs, 4294967296.);
   if (d < 0) {
       *most_significant_word = ~*most_significant_word;
       *least_significant_word = ~*least_significant_word + 1;
       if (!*least_significant_word) *most_significant_word += 1;
   }
}

关于c - 在 C89 中,如何将 double 浮点截断并拆分为两个 32 位字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35700577/

相关文章:

c - 以下表达式的行为是否明确定义?

c - C中线程间的消息传递

c - 为什么 C 编译器在外部名称前加上下划线?

c - 删除数组中间的元素?

c - (int (*)[])var1 代表什么?

c - 分段不清错误返回 139

c - 逻辑错误?程序没有像我希望的那样工作

c++ - CreateProcess() 启动子应用程序

c - 使用灵活的数组成员分配结构

c - Makefile 编译错误未应用 -std=c99