C/C++判定是否为平方数以及由此引出的IEEE754(1)
2013-02-01 17:23
357 查看
本部分介绍相关背景知识
1、C语言的char, short, int, long, long long类型都是由C自身规定的,但是float, double, long double都是没有规定的(unspecified),但大多数平台上的实现遵从IEEE754标准(参见http://en.wikipedia.org/wiki/C_data_types)
(C99标准似乎规定了float对应IEC60559 single format,double对应IEC60559 double format,long double推荐实现为IEC60559 extended format,参见C99标准文档442页Annex F)
IEC60559应该是IEEE754的别名:
“该标准的全称为IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985),又称IEC 60559:1989,微处理器系统的二进制浮点数算术(本来的编号是IEC 559:1989)”(http://zh.wikipedia.org/wiki/IEEE_754)
2、将一个int类型变量赋给double类型变量,是不会损失精度的;但是将一个long long类型变量赋给double,可能损失精度
IEEE754规定的double的格式是(参考http://en.wikipedia.org/wiki/Double_precision_floating-point_format)
sign是符号位,exponent是以无符号二进制表示的指数,上图表示的数
,其中b-1b-2...b-52就是图中fraction部分,e就是exponent。即
从此式可以看出,当e-1023>52时,两个相邻的double数之间的距离就不是1,而要>1。例如e-1023=53时,两个相邻的double数之间的距离是2,看下面的测试代码
每次x加1.5时,会找到最近的double值赋给x;如果是加1的话,这里10个数完全相同。
这里有一段话(来自http://stackoverflow.com/questions/4317988/ieee-754-floating-point-precision-how-much-error-is-allowed/4319151#4319151)
The IEEE-754 standard requires that so called "basic operations" (which include addition, multiplication, division and square root) are correctly rounded. This means that there is a unique allowed answer, and it is the closest representable floating-point number to the so-called "infinitely precise" result of the operation.
这里还有一段(来自http://stackoverflow.com/questions/14151740/sqrt-perfect-squares-and-floating-point-errors/14152959#14152959)
In IEEE 754 floating-point, if the double-precision value x is the square of a nonnegative representable number y (i.e. y*y == x and the computation of y*y does not involve any rounding, overflow, or underflow), then sqrt(x) will return y.
This is all because sqrt is required to be correctly-rounded by the IEEE 754 standard. That is, sqrt(x), forany x, will be the closest double to the actual square root of x. That sqrt works for perfect squares is a simple corollary of this fact.
1、C语言的char, short, int, long, long long类型都是由C自身规定的,但是float, double, long double都是没有规定的(unspecified),但大多数平台上的实现遵从IEEE754标准(参见http://en.wikipedia.org/wiki/C_data_types)
(C99标准似乎规定了float对应IEC60559 single format,double对应IEC60559 double format,long double推荐实现为IEC60559 extended format,参见C99标准文档442页Annex F)
IEC60559应该是IEEE754的别名:
“该标准的全称为IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985),又称IEC 60559:1989,微处理器系统的二进制浮点数算术(本来的编号是IEC 559:1989)”(http://zh.wikipedia.org/wiki/IEEE_754)
2、将一个int类型变量赋给double类型变量,是不会损失精度的;但是将一个long long类型变量赋给double,可能损失精度
IEEE754规定的double的格式是(参考http://en.wikipedia.org/wiki/Double_precision_floating-point_format)
sign是符号位,exponent是以无符号二进制表示的指数,上图表示的数
,其中b-1b-2...b-52就是图中fraction部分,e就是exponent。即
从此式可以看出,当e-1023>52时,两个相邻的double数之间的距离就不是1,而要>1。例如e-1023=53时,两个相邻的double数之间的距离是2,看下面的测试代码
#include <stdio.h> int main(int argc, const char *argv[]) { double x = 9007199254740992ll;//2^53 //x = 4503599627370496ll;//2^52 for (int i = 0; i < 10; i++) { printf("%lf\n", x); x = x + 1.5; } return 0; } /* 输出是: 9007199254740992.000000 9007199254740994.000000 9007199254740996.000000 9007199254740998.000000 9007199254741000.000000 9007199254741002.000000 9007199254741004.000000 9007199254741006.000000 9007199254741008.000000 9007199254741010.000000 */
每次x加1.5时,会找到最近的double值赋给x;如果是加1的话,这里10个数完全相同。
这里有一段话(来自http://stackoverflow.com/questions/4317988/ieee-754-floating-point-precision-how-much-error-is-allowed/4319151#4319151)
The IEEE-754 standard requires that so called "basic operations" (which include addition, multiplication, division and square root) are correctly rounded. This means that there is a unique allowed answer, and it is the closest representable floating-point number to the so-called "infinitely precise" result of the operation.
这里还有一段(来自http://stackoverflow.com/questions/14151740/sqrt-perfect-squares-and-floating-point-errors/14152959#14152959)
In IEEE 754 floating-point, if the double-precision value x is the square of a nonnegative representable number y (i.e. y*y == x and the computation of y*y does not involve any rounding, overflow, or underflow), then sqrt(x) will return y.
This is all because sqrt is required to be correctly-rounded by the IEEE 754 standard. That is, sqrt(x), forany x, will be the closest double to the actual square root of x. That sqrt works for perfect squares is a simple corollary of this fact.
相关文章推荐
- C/C++判定是否为平方数以及由此引出的IEEE754(2)
- C/C++判定是否为平方数以及由此引出的IEEE754(3)
- C/C++ 判断文件夹是否存在以及创建、删除文件夹 windows以及linux通用
- ”()“和”[]“引发的血案——由此引出C++中关键词new
- C++中四种类型转换以及const_cast是否能改变常量的问题
- Solaris内存管理以及判定内存是否够用的方法
- 给定一个向量/数组,判定该向量/数组是否为一个二叉搜索数的后续遍历C++
- C++注册,卸载OCX控件,以及判断是否注册
- 无论程序是否安装,都使setup.exe直接进入安装状态,不出现反安装;以及由此延伸出的同一安装程序允许在同一机器上安装多套软件的探讨
- C/C++ 判断文件夹是否存在以及创建、删除文件夹 windows以及linux通用
- C++中四种类型转换以及const_cast是否能改变常量的问题
- 判定200以内的数字的平方是否为回文数
- C++ 浮点数(double、float)如何定义NaN、正无穷、负无穷,以及如何判断是否是NaN
- C++中四种类型转换以及const_cast是否能改变常量的问题
- C/C++ 判断文件夹是否存在以及创建、删除文件夹 windows以及linux通用
- C++基于递归和非递归算法判定两个二叉树结构是否完全相同(结构和数据都相同)
- C/C++ 判断文件夹是否存在以及创建、删除文件夹 windows以及linux通用
- C++判断用户输入路径是否正确(判断盘符是否存在以及“\”与"/")
- C++ 浮点数(double、float)如何定义NaN、正无穷、负无穷,以及如何判断是否是NaN
- 【C++编程题】高效判断单链表是否有环以及单链表的创建