为清楚起见,如果我使用的是实现IEE 754浮点数的语言,我声明:
float f0 = 0.f;
float f1 = 1.f;
Run Code Online (Sandbox Code Playgroud)
...然后将它们打印出来,我会得到0.0000和1.0000 - 完全正确.
但IEEE 754无法表示实线上的所有数字.接近于零,"差距"很小; 当你越走越远时,差距越来越大.
所以,我的问题是:对于一个IEEE 754浮点数,这是第一个(最接近零)整数,无法准确表示?我现在只关心32位浮点数,虽然如果有人给出它我会有兴趣听到64位的答案!
我认为这就像计算2 bits_of_mantissa并添加1 一样简单,其中bits_of_mantissa是标准公开的位数.我在我的机器(MSVC++,Win64)上为32位浮点数做了这个,但它看起来很好.
使用Bash时,我可以将一个命令的输出放到另一个命令中,如下所示:
my_command `echo Test`
Run Code Online (Sandbox Code Playgroud)
会是一样的
my_command Test
Run Code Online (Sandbox Code Playgroud)
(显然,这只是一个非实际的例子.)
我只是想知道你是否可以批量做同样的事情.
我读过关于浮点的内容,我知道NaN可能来自操作.但我无法完全理解这些概念是什么.有什么区别?
在C++编程期间可以生成哪一个?作为程序员,我可以编写一个程序来导致sNaN吗?
我以前认为在C99中,即使函数的副作用f和g干扰,虽然表达式f() + g()不包含序列点,f并且g会包含一些,所以行为将是未指定的:要么f()之前调用f()之前的g()或g().
我不再那么肯定了.如果编译器内联函数(即使未声明函数,编译器可能决定这样做inline)然后重新排序指令,该怎么办?可能有人得到上述两种不同的结果吗?换句话说,这是未定义的行为吗?
这不是因为我打算写这种东西,而是在静态分析器中为这样的语句选择最佳标签.
c c99 undefined-behavior sequence-points unspecified-behavior
当允许使用的唯一浮点指令是387个时,几乎不可能(*)以合理的成本提供严格的IEEE 754语义.当希望保持FPU在完整的64位有效数字上工作时,这一点特别困难,因此该long double类型可用于扩展精度.通常的"解决方案"是以唯一可用的精度进行中间计算,并在或多或少明确定义的场合转换为较低的精度.
根据Joseph S. Myers在2008年GCC邮件列表中发布的解释,GCC的最新版本处理中间计算中的过多精度.gcc -std=c99 -mno-sse2 -mfpmath=387据我所知,这个描述使程序编译完全可预测,到最后一点.如果它偶然没有,那就是一个错误而且它将被修复:约瑟夫S.迈尔斯在他的帖子中声明的意图是使其可预测.
是否记录了Clang如何处理超额精度(比如何时使用该选项-mno-sse2),以及在哪里?
(*)编辑:这是夸大其词.当允许将x87 FPU配置为使用53位有效数字时,这有点令人讨厌,但并不难以模拟binary64.
在下面的R ..评论之后,这里是我与Clang的最新版本之间的短暂互动的日志:
Hexa:~ $ clang -v
Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
Hexa:~ $ cat fem.c
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <fenv.h>
double x;
double y = 2.0;
double z = 1.0;
int main(){
x = y + z;
printf("%d\n", (int) FLT_EVAL_METHOD);
}
Hexa:~ $ clang …Run Code Online (Sandbox Code Playgroud) 是否有一个OCaml库可以利用IA-32和x86-64架构上的80位扩展精度浮点类型?
我知道MPFR绑定,但我理想的库会更轻量级.利用历史浮点指令将是理想的.
似乎IEEE 754标准将16,777,214个32位浮点值定义为NaN,或所有可能值的0.4%.
我想知道保留这么多有用值的理由是什么,而基本上只需要2个:一个用于信令,一个用于安静的NaN.
对不起,如果这个问题很简单,我在互联网上找不到任何解释.
像"libgtk + -devel"或"python-devel"等开发包的效用是什么?它们是否包含图书馆的来源?它与libgtk +等非开发包有什么不同?
从我系统的手册页:
void*memmove(void*dst,const void*src,size_t len);
描述
memmove()函数将字符串src中的len个字节复制到字符串dst.
两个字符串可能重叠 ; 副本总是以非破坏性的
方式完成.
从C99标准:
6.5.8.5比较两个指针时,结果取决于指向的对象的地址空间中的相对位置.如果指向对象或不完整类型的两个指针都指向同一个对象,或者两个指针都指向同一个数组对象的最后一个元素,则它们相等.如果指向的对象是同一聚合对象的成员,则指向稍后声明的结构成员的指针比指向结构中先前声明的成员的指针大,指向具有较大下标值的数组元素的指针比指向同一数组的元素的指针大.具有较低的下标值.指向同一个union对象的成员的所有指针都比较相等.如果表达
P指向数组对象的元素,表达式Q指向同一数组对象的最后一个元素,指针表达式Q+1比较大于P.在所有其他情况下,行为 未定义.
重点是我的.
的参数dst和src可被转化为指针char以便减轻严格别名的问题,但有可能以比较两个指针可以指向内部的不同的块,以便做以正确的顺序的拷贝的情况下,它们指向相同的块内?
显而易见的解决方案是if (src < dst),但未定义如果src和dst指向不同的块."未定义"意味着您甚至不应该假设条件返回0或1(这在标准词汇表中称为"未指定").
另一种选择是if ((uintptr_t)src < (uintptr_t)dst),至少是未指定的,但我不确定标准是否保证何时src < dst定义,它等同于(uintptr_t)src < (uintptr_t)dst).指针比较是从指针算法定义的.例如,当我在添加时阅读第6.5.6节时,在我看来,指针算法可以与uintptr_t算术相反的方向,即兼容的编译器可能具有,当p类型为char*:
((uintptr_t)p)+1==((uintptr_t)(p-1)
Run Code Online (Sandbox Code Playgroud)
这只是一个例子.一般来说,将指针转换为整数时,似乎可以保证很少.
这是一个纯粹的学术问题,因为memmove它与编译器一起提供.在实践中,编译器作者可以简单地将未定义的指针比较提升为未指定的行为,或者使用相关的编译指示强制其编译器memmove正确编译它们.例如,此实现具有以下代码段:
if ((uintptr_t)dst < (uintptr_t)src) {
/*
* As author/maintainer of libc, take advantage …Run Code Online (Sandbox Code Playgroud)