整型和浮点型相减的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整型和浮点型相减的问题相关的知识,希望对你有一定的参考价值。

为什么double的12减去int的12没有结果呢?是不是double表示12是11.5*******--12.4********啊。
我想把带小数的double数转换成不代小数的数,并统计有几个小数数位,如4.2356转换成42356,小数数位是4。请问该如何用代码实现?
我的愚见是:
while((r-(int)r)!=0)//将小数转换成整数

r*=10;
m++;//保存小数的位数

结果是个死循环。

printf("%lf",double(12)-int(12));
有结果,是12.0.
double的12就是12.0

解释为什么是死循环-
浮点数是二进制存储,而精确的浮点二进制存储为,整数是2的+n次方的算术和,小数是2的-n次方的算术和.例如0.5、0.25、0.125此类小数可以精确表示,而诸如0.1、0.17这类小数就有误差,具体体现在浮点数的位数波动,实际的存储值可能编程了0.1000125、0.17000025之类.
double和int的算术运算向double对齐,所以r-int(r)是一个浮点数,显然当r不是精确二进制小数时,表达式的结果含有小数位,不为double(0),会循环下去.当r较小的时候,表达式的结果仅为一个较小的纯小数,当r增大到超过int的极值+2147483648后,(int)r会被截断,r-int(r)从纯小数陡增为极大的浮点数.死循环
你可以尝试在你的设计中,把r=4.2356改成r=4.125,则不为死循环,可以得到预期结果
或者你改成r-(int)r>0.0001,这样就只有当r的小数位超过10位的截断问题.比如r=4.2356时还是无法计算,因为实际存储位数超过10位,(int)r被截断后表达式变成很大的浮点数,死循环.

我提供如下算法.判断标准比较类似>0.0001这种精确度的折中法,每次*10后判断个位,连续3次个位为0则退出循环

#include "stdio.h"
main()

double r;scanf("%lf",&r);
double r1=(int)r;int m=0,n=0,g;
//g表示个位,r1结合r计算个位
while(1)

r*=10;
r1*=10;
g=int(r-r1);
//这样提取个位比g=int(r)%10可表达的r大,后者r过大会被截断
r1+=g;
m++;
if(!g)n++;
else n=0;
if(n==3)break;

printf("%lf %d",r1/1000,m-3);

要注意的是,结果的r1/1000和m-3中只有m有效,表示浮点数实际存储的小数位,而r1在增大的过程中,可能由于位数过长而被截断,成为误差值.例如r=4.2356时,就只有m有效
参考技术A //double 是不精确的, 如果你用单步跟踪, 会发现输入1.2035, 其值是1.203500000000xxx, 所以不能把它与某个具体的数值相比, 须确定一个极小区间如: 1e-5, 如下示:
while ( r - floor(r) > 1e-5 )本回答被提问者采纳
参考技术B (r-(int)r)!=0
永远不可能是假``
就想你说的` double 小数是不确定的` 他是实数`所以会造成死循环

44这样写
(int)(r-(int)r)!=0

java运算疑惑 整型和浮点型混合运算

int a=90;
float b=10.98f;
float c=a+b;
结果c=100.979996
int a=10
float b=90.98f
float c=a+b;
结果c=100.98

参考技术A 这是因为java的浮点运算并不是依靠简单的加减算法来计算的
java本身的浮点运算一直都是有这样的问题的
如果你要精确的小数计算的话,建议使用BigDecimal
这是目前比较好的解决方法本回答被提问者采纳
参考技术B 整型和浮点型相加会JVM会自动将整形转为浮点型

以上是关于整型和浮点型相减的问题的主要内容,如果未能解决你的问题,请参考以下文章

go语言基础-数据类型- 整型,浮点型,布尔型

go语言基础-数据类型- 整型,浮点型,布尔型

Python-整型/浮点型和字符串数据类型-190819

整型和浮点数据的储存

《从零开始学Swift》学习笔记(Day 13)——数据类型之整型和浮点型

整型除以浮点型是啥型?