首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NetBSD长双故障

NetBSD长双故障
EN

Stack Overflow用户
提问于 2016-01-29 17:19:22
回答 1查看 178关注 0票数 3

我有一个简单的代码:

代码语言:javascript
复制
 #include <stdio.h>

 int main()
 {
      //char d[10] = {0x13, 0x43, 0x9b, 0x64, 0x28, 0xf8, 0xff, 0x7f, 0x00, 0x00};
      //long double rd = *(long double*)&d;
      long double rd = 3.3621e-4932L;
      printf("%Le\n", rd);
      return 0;
 }

在我的Ubuntu x64上,它按预期打印3.362100e-4932。在我的NetBSD上,它打印1.681050e-4932

为什么会发生这种情况,我该如何解决呢?我试着用相同的结果来尝试clang和gcc。

我的系统(VM在VirtualBox 5.0中):

代码语言:javascript
复制
 uname -a
 NetBSD netbsd.home 7.0 NetBSD 7.0 (GENERIC.201509250726Z) amd64

 gcc --version
 gcc (nb2 20150115) 4.8.4

 clang --version
 clang version 3.6.2 (tags/RELEASE_362/final)
 Target: x86_64--netbsd
 Thread model: posix

仅供参考

/usr/include/x86/float.hLDBL_MIN定义为3.3621031431120935063E-4932L,此值大于printf结果。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-29 18:16:18

/usr/include/x86/float.hLDBL_MIN定义为3.3621031431120935063E-4932L,此值大于printf结果。

LDBL_MINlong double型的最小正归一化值。类型可以表示较小的数字,它们只是低于正常值。

我只能在NetBSD上推测问题的性质,但主要有两种可能性:

  1. 编译器将您的初始化常量转换为一个低于正常值的值,这个数字(在相对意义上)与所请求的值相当远。
  2. 这个数字被翻译得很好(但结果仍然低于正常值),而且NetBSD的printf()对于低于正常的数字,或者至少对这个数字来说是错误的。

打印的数字是您预期值的一半,这一事实表明long double表示中的(二进制)指数存在问题。考虑到IEEE对低于法线数的格式的细节,很容易想象一个printf()实现如果没有预期到低于正常数的值,就会错误地解释(二进制)指数字段来表示比实际表示的值少一个指数,因此打印的值是预期值的一半。这将是我对正在发生的事情的猜测。

您可能还可以通过打印(例如,rd * 4 )来区分错误的值和错误的显示情况。无论哪种方法,这都应该在正常数字的范围内,因此人们会假设特定于低于正常数的printf()错误不会影响打印它。

至于如何进行,您有几个选择。我最可能想到的是:

  1. 避免低于正常值的数字。这可能不实用,但至少您可以使用LDBL_MIN作为初始化器,而不是最接近于低于正常的long double的常量。
  2. 忽略这个问题。如果您能够确认这是一个显示问题,而不是一个错误的值问题,那么您可能不需要做任何事情来充分服务于您更大的目标。
  3. 修复NetBSD的C库。假设问题在printf()中,修复可能不会很大,而且库是开源的,就像系统的其他部分一样。
  4. 提交错误报告并等待其他人修复它。如果您需要一个及时的修复,那么这可能是不合适的,但如果您有时间等待,那么这需要您很小的努力。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35090322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档