iostream-浮点数输出很多位小数出现错误

问题描述

浮点数输出很多位小数出现错误
 #include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    char str[1000];
    sprintf(str,"%.100lf",(double)1/250);
    cout<<str;
}

运行这个程序得到的结果是
0.004000000000000000000000000000000中间有一段非零数字
00000000000000000000

解决方案

解决方案二:

浮点数在计算机中其实是一种不精确的表示,它的计算是一种实数的近似值计算,存在舍入(rounding)误差,不够精确,你这个输出结果是很正常的。

解决方案三:

浮点数无法在计算机中精确存储,比如存0.004也只是存一个无限接近0.004的数
可能存成0.0040000000000001也可能是0.003999999999999
参考:http://www.cnblogs.com/dolphin0520/archive/2011/10/02/2198280.html

解决方案四:

把%.100lf改为%.100f试试 ,不写那个l

解决方案五:

http://ask.csdn.net/questions/248943可以参考这里我的回答。根据原文http://wenku.baidu.com/link?url=j8tNlNuV1xovu3jBR_DEdJ3o5amLsDgReUR8wcZhvUr1DT3_3q7qJ1yX7M_ZESRr-tZTMgZLl5sR2Fa-5OONfsCnw_eVVlWmXL-nidrRZju

解决方案六:

参考原文http://wenku.baidu.com/link?url=j8tNlNuV1xovu3jBR_DEdJ3o5amLsDgReUR8wcZhvUr1DT3_3q7qJ1yX7M_ZESRr-tZTMgZLl5sR2Fa-5OONfsCnw_eVVlWmXL-nidrRZju

你去百度下浮点数的存储格式。机器只能识别0,1,需要二进制转换成十进制。理论上,有限位数的二进制浮点数必能转换为有限位数的十进制数;但对于有限位数的十进制浮点数,转换为二进制数不能保证是有限位数,且多数情况下不是有限位数。因此,如果提供足够的输出位数,二进制浮点数可以精确转换为十进制数,不产生转换误差。但是,由于没有一个2n与lOm(n,m为整数)相等,二进制和十进制相互转换的位数没有简单的若干位对应若干位的对应关系。一般地,二进制浮点数向十进制转换都只提供若干位的近似值,并不提供全部的数字位数。事实上更主要的原因是:计算机中表示的二进制浮点数绝大多数本身就是实际数值的近似值,从有效数字的角度看,转换为十进制数时提供更多位数字并无使用价值。这里自然就有一个如何看待和精确使用数值的问题,即有效数字位数的问题。尤其对于各种数值计算,必须掌握其有效数字位数。但查阅有关资料,没有看到对计算机中浮点数的有效数字位数的准确叙述,一般仅指出fIoat和doubIe型大致的有效数字位数,且说法不一,没有给出依据。在此,从相对误差(误差绝对值与数值绝对值的比值)的角度给出一般性的结论。
http://ask.csdn.net/questions/248943

解决方案七:

大哥。。1/250不等于0.004等于什么?你str里面的值存的不就是1/250的值么?你真的是想问这个问题么?你是想输出0.000000000000000000000000?

解决方案八:

看错。请LZ无视我。。。。。

解决方案九:

首先编译器会把 (double) 1/25 转换成双精度浮点型

what is float-point format ? 一般 通用的编译器都会采用IEEE Standard 754标准 (such as 微软的编译器)

我们比较熟悉的有 单精度 (float 32bit) 双精度(double 64bit) 还有扩展精度( 80bit 比较少见, 所以不讨论) 不知你对变量的理解是怎样的 但在我的
眼里不管什么变量 都是 一字节 两字节 四字节 八字节的二进制码 所以我会以二进制码的形式讲解
注意:计算机只认识二进制 0和1 也就是低电平和高电平

float 总共有32位 0~22位是有效数字 23~30位是指阶码 第31位是符号位 从0开始数 到31 刚好32位 所以别再懊恼 我是sb吗 明明说32位 你却到31
double 总共有64位 0~51位是有效数字 52~62位是阶码 第63位是符号位
有效数字: 当然是有效的数字了 是不是 真不好解释 比如 1/3 =0.3333333333........ 我要保留两位有效数字 则1/3=0.33 呵呵
阶码:相似指数 但他是二进制的指数 而且在IEEE-754标准中需要加上一个特殊值 等等 你不必过分纠结 后面会详细的

符号位:就是数学里的正 负了 若该位为零 是正数 若该位为1 是负数
例如: 将十进制数100.25转换成单精度的格式的数(32位)
100.25 => 1100100.01
1100100.01 =>1.10010001*2^6 小数点的左边必须是1 而且是只有一个1 (人家规定的 不要问为什么)
正数 符号位:0
因为指数6(十进制)=110(二进制) 所以 阶码 : 110+01111111=10000101 为什么指数+特殊值 下面解释
有效数字:10010001000000000000000 (23位) 小数点左边的1哪去了呢 被隐藏了 iee规定二进制的
小数点左边必须是1 为什么这样规定啊 当然是为了扩大数字的取值范围啦 你想想如果在正常数值格式
转换成浮点格式时 把小数点的左边的1隐藏 在浮点格式转正常格式时 再加上这个1 我们就可以在32位的
空间中多加一位了
为什么阶码是 二进制的指数+01111111(32位 64位又不同) 我觉得是和能加速比较大小的速度 首先我们都是
1.xxxxxx 这样的格式 当我们的指数越大 值就越大 当指数是正数时 最高位肯定是0 所以加上这个值肯定最
高位的值为1 当指数是负数时 最高位肯定为1 所以加上这个值 最高位的值肯定就是0了 这样 就能通过比较
指数的大小来比较整个值了 只有当这两个指数值相等时 才比较有效数字 在加减运算 乘除运算应该也能起到
加速作用 当然了 也可能并没有什么加速作用 可能最大的原因是能简化硬件的设计 降低成本 这都是我猜的 因为
我也不是硬件设计的 但不管怎么做 都是有原因的 呵呵

只要按iee-745的规定就可以了 你可以百度一下

ok 大致的认识就讲的这里 我们来讨论你的问题吧 别说 你还不懂 我最讨厌了 你不懂 难道不会百度啊 最好google
(double)1/25 是双精度 是一个64位双精度值

首先将 1转换成双精度格式的二进制值 : 数值后面加D 表示十进制 加b表示二进制 加h表示十六进制
1d=1b

所以 符号位:0 阶码: 0b+01111111111b=01111111111b=3ffH(十六进制哦) 加01111111111b是双精度的 (iee规定的)
有效数字:0b
所以在内存中的值是 : 3ff0 0000 0000 0000h 用十六进制表示 64位的数
25转换成双精度的格式的二进制值:
25d=11001b=1.1001*2^4 b 你如果说我不知道怎么转换啊 我也没办法啊 我也是用计算器的 原理哪里都能找到
正数 符号位:0 阶码 4d+01111111111b=100b+01111111111b=10000000011b=403h
有效数字:1001b
所以在内存中的值是:4039 0000 0000 0000h

嗯 然后把这两个64位的值装入fpu的数据寄存器中 然后执行除操作
得到结果为 3fa4 7ae1 47ae 147b h (h是十六进制) 你迷茫了 或者在敬佩我 “大神啊" :> 哈哈哈哈
我也不是自己用纸和笔算出来的 我用的是编译器 反汇编出来的 当然了 编译器也是基于理论计算出来的 (通过fpu)
为什么是这个数 啊 i don't know 这关系到硬件方面的 东西

我们看看 3fa4 7ae1 47ae 147b h 是什么
符号位为0 所以是正数 3fah=011 1111 1010b 指数= 011 1111 1010b-011 1111 1111b=111 1111 1011b=-5
4 7ae1 47ae 147bh=0100 0111 1010 1110 0001 0100 0111 1010 1110 0001 0100 0111b
ok
最终二进制值为 0.0000 1010 0011 1101 0111 0000 1010 0011 1101 0111 0000 1010 00111b
即 2^(-5)+2^(-7)+2^(-11).......... 接近于 1/25

至于为什么 0.040000000中间有数字00000000 可能和 sprintf函数的转换有关 因为这是一个非常复杂的转换 只能近似 而不能一定准确
当然了 你真想知道答案 那就把sprintf函数的源代码看一遍吧

解决方案十:

ieee 754浮点数标准

时间: 2025-01-11 13:10:01

iostream-浮点数输出很多位小数出现错误的相关文章

Javascript浮点数乘积运算出现多位小数的解决方法

 这篇文章主要介绍了Javascript浮点数乘积运算出现多位小数的解决方法,需要的朋友可以参考下 Javascript在进行浮点数的乘积运算,会出现多位小数的情况.    这是由于在运算的时候先把浮点数转化成二进制后进行运算,但是有的小数在二进制编码后出现无限循环,因而导致计算出现了误差,在其它变成语言中也有类似的问题.    原因解释参考自百度知道:    例如:求1038.1-1000  1038.1=10000001110.00011001100110011001100110011001

javascript-怎么格式化用户输入的浮点数,要求保留两位小数

问题描述 怎么格式化用户输入的浮点数,要求保留两位小数 用javascript语句怎么格式化用户输入的浮点数,要求保留两位小数 解决方案 Number.toFixed(2) 解决方案二: <script language="javascript"> document.write("<h1>JS保留两位小数例子</h1><br>"); var a=2.1512131231231321; document.write(&q

VC++浮点数四舍五入保留两位小数VC++浮点数四舍五入保留两位小数

问题描述 VC++浮点数四舍五入保留两位小数VC++浮点数四舍五入保留两位小数 VC++浮点数四舍五入保留两位小数VC++浮点数四舍五入保留两位小数 解决方案 http://zhidao.baidu.com/link?url=tECI6Q8RqTZLAQfx7m5GKgdj9GTDy5XwIAu7pB_Ch74oF6EAif4TzLgjyFL-6llZBGs5pr9teO3MYQn5pV-0_a 解决方案二: Double?a?=?12.345678;????????????Console.Wr

勋-c,输入六个学生成绩,求平均分,保留两位小数,要求用数组!基础题,学生,勿喷

问题描述 c,输入六个学生成绩,求平均分,保留两位小数,要求用数组!基础题,学生,勿喷 输入六个学生成绩,求平均分,保留两位小数,要求用数组!基础题,学生,勿喷 #include int main() { int i,t,sum=0; int a[6]; for(i=0;i<6;i++) scanf("%d",&a[i]); for(i=0;i<6;i++) sum=sum+a[i]; t=sum/6; printf("平均值为:%.2dn",t

c++-C++负数小数如何不按四舍五入保留两位小数

问题描述 C++负数小数如何不按四舍五入保留两位小数 C++负数小数如何不按四舍五入保留两位小数................................. 解决方案 #include <iostream> double foo(double n) { bool sign = n < 0; if (n < 0) n = 0 - n; n = ((int)(n * 100.0)) / 100.0; if (sign) n = 0 - n; return n; } int mai

java 保留两位小数的几种方法_java

1.代码: import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; public class format { double f = 111231.5585; public void m1() { BigDecimal bg = new BigDecimal(f); double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP)

js小数运算出现多位小数如何解决_javascript技巧

和大家分享一个有趣的测试: 0.1+0.2 == 0.3 //false 顿时郁闷,好吧!原来0.1+0.2变成:0.30000000000000004 再来一个 2.4/0.8 =>2.9999999999999996 没办法换种方式,都转换成整数 (2.4 * 100)/(0.8 * 100) 10.22 现在要减去 0.11 结果值又出现了很多的小数 10.110000000000001,然后我就用了 toFixed 方法来过滤小数,但是不知道跟前面那种转换成整数后再执行哪种效率高,好!还

JS保留两位小数

    JS保留两位小数       对于一些小数点后有多位的浮点数,我们可能只需要保留2位,但js没有提供这样直接的函数,所以我们得自己写函数实现这个功能,代码如下: function changeTwoDecimal(x) {    var f_x = parseFloat(x);    if (isNaN(f_x))    {       alert('function:changeTwoDecimal->parameter error');       return false;    

Javascript浮点数保留两位小数点示例代码

 本篇文章主要介绍了js浮点数保留两位小数点示例代码(四舍五入) 需要的朋友可以过来参考下,希望对大家有所帮助  代码如下: var changeTwoDecimal_f= function (floatvar){       var f_x = parseFloat(floatvar);       if (isNaN(f_x)){           return '0.00';       }       var f_x = Math.round(f_x*100)/100;       v