我们如何将浮点数拆分为整数和小数部分?
Posted
技术标签:
【中文标题】我们如何将浮点数拆分为整数和小数部分?【英文标题】:How can we split a floating point number to its integer and decimal parts? 【发布时间】:2019-10-15 12:34:45 【问题描述】:我想检测像 235.102457
这样的数字的浮点和整数部分。
总之想存储我号码的两部分,例如:
A=235
B=102457
如何拆分这个号码?
【问题讨论】:
mathworks.com/matlabcentral/answers/… 您的问题和您接受的答案有冲突。你想要B=102457
,根据问题,还是B=0.102457
,根据接受的答案?请注意,获得前者要困难得多。
你能确认你想要B = 102457
而不是B = 0.102457
吗?
负数的输出应该是什么?
另外请详细说明您希望如何设置小数部分的精度。大多数答案需要知道您要保留的位数。
【参考方案1】:
x=235.102457;
tmp = strsplit(num2str(x,16),'.'); % Cast to string, split on the dot
A = str2num(tmp1); % = 235
B = str2num(tmp2); % = 102457
您可以使用num2str()
将数字转换为字符串,使用strsplit()
在点上分割,然后使用str2num()
将每个部分转换回双精度数。
注意对num2str
的调用中的16
:默认情况下,字符串中只有4 个小数位。基本上任何足够高的数字都可以,只要你的数字的小数部分小于这个。不过,将其设置得更高会增加运行时间。
在数字上做到这一点很困难。指定小数位数然后四舍五入,就像其他答案一样,工作,但有一个缺点,例如1.1, 1.0, 1.100
等的处理方式相同。由于数值精度,尝试递归查找功率不起作用:
x = 235.102457;
A = fix(x);
tmp = x-A;
tmp*10^6
ans =
1.024569999999869e+05 % i.e. needs rounding
kk = 0;
while kk<32 && ~(mod(tmp,1)==0)
tmp = tmp*10;
kk = kk+1;
end
tmp
tmp =
1.024569999999869e+16 % Gets a lot of floating point garbage
在循环中没有办法知道什么时候四舍五入,因此试图递归地找到有效数字的数量,在这种情况下 kk
失败(除非舍入魔法以某种方式设法舍入而不剥离所需的小数位)。
【讨论】:
这是更通用的方法。 (+1)str2double
不是更好的做法吗?
@UnbearableLightness,因为 MATLAB 一直在警告我:是的,以防您想要双数。不过我喜欢str2num
,因为它更通用,因为它可以提供各种输出。在这种情况下,str2num()
将输出设置为整数实际上是可能的,并且会大大减少输出大小,因为无论如何所有数字都是整数。【参考方案2】:
我认为这可行(仅在 Octave 中测试过):
x = 235.102457
A = floor(x)
B = mod(x,1)
【讨论】:
您是否针对x = -235.102457
进行了测试...这不适用于负数。 fix
函数可能更合适。
这在技术上将保存 B = 0.102457
,而不是像 OP 最初要求的那样保存 102457
。他们可能只是在他们的问题陈述中不清楚,因为他们确实接受了这一点。
@Adriaan 哦,你是对的,我的错!我认为你的方法更好。
我不确定“更好”;如果 OP 想要他们在问题中要求的内容,那么是的,我的是正确的。如果他们想要他们接受的东西,即这个答案,那么就使用这个。当纯数字足够时遍历字符串会增加很多不必要的开销和计算时间。
如果担心负数,fix
可能是比floor
更好的选择【参考方案3】:
这应该适用于负数:
nDecimalDigit = 9 ;
A = fix( x ) ;
B = round( abs(x-A) * 10^nDecimalDigit ) ;
fix()
函数向零舍入,无论是负数还是正数,它都会返回相同的整数部分(与分别向负无穷和正无穷舍入的 floor
或 ceil
不同)。
由于A
保留了原始输入的符号,我猜你不需要符号在小数部分B
,所以我们使用abs()
取消符号。
我们将此十进制数乘以一个因数,具体取决于您要保留的位数,然后我们进行最后的舍入以修剪该数字中剩余的小数部分。
【讨论】:
这有 the same problem 作为其他两个答案:您需要知道存在的位数,如果您输入更高的数字,您会得到一个不同的整数值,数量级. 我很清楚,但这不是一个问题,因为它不违反问题。这部分问题还没有限制在问题中。在 OP 描述一组受限的输入或为每个浮点表示定义要采用的行为之前,我们只能提出“百万种方法中的一种......”我们大多数熟悉浮点的人建议控制预先数字。如果 OP 有更好的主意,我迫不及待想听听! 我承认我的观点。1.1
等于 1.100
(禁止浮点),所以问题是 OP 认为“小数分隔符后面的部分”,因为从技术上讲,您可以在不更改数字的情况下在点后面添加无限零。
没错!但是,鉴于 OP 接受(不完整)答案的速度,我认为他甚至从未考虑过这部分。他只是选择了适用于他的具体案例的第一个答案,恐怕我们再也不会听到他的消息了(至少在这个问题上没有)......【参考方案4】:
假设你想保留 6 位小数,那么你可以这样做:
x = rand * 1000;
dec = 6;
A = round(x);
B = round((x-A)*10^dec);
【讨论】:
如果向上四舍五入,你不会冒着被A
减一的风险吗?
除了逐一错误之外,这也不容易概括,因为您已经需要知道小数位数才能拆分它。那你最好先手写。以上是关于我们如何将浮点数拆分为整数和小数部分?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不进行任何舍入的情况下将浮点数转换为小数点后 4 位?