【问题标题】:Algorithmic or Mathematical way of separating decimal from floating?将小数与浮点数分开的算法或数学方法?
【发布时间】:2013-04-08 20:15:24
【问题描述】:

是否有任何数学或算法方法将浮点数分成两部分(在点之前和之后)。

例子:

number=456.789
before=456
after=0.789

我不想要任何代码,因为我可以用任何编程语言来做到这一点。我想要一个通用算法,最好使用算术或其他此类运算符。

【问题讨论】:

  • 您希望我们考虑内存中的 IEEE754 浮点表示吗?我们可以使用数学函数天花板和地板吗?

标签: algorithm math floating-point decimal exponent


【解决方案1】:

我通常会执行以下操作来获得您的要求:

double number=456.789;
int before= number; //This type cast is equivalent to floor(number) 
double after=number-before;

所以获取给定浮点数的下限是我们执行的主要任务,其中 floor 方法只返回不大于输入数的最大整数。这很可能是通过利用内存中的floating point representation 进行一些语言级别的操作来完成的(您不能在浮点数中执行正常的按位运算,因为它没有定义)。 所以AFAIU,如果你不想使用地板/打字,你基本上注定要失败。

【讨论】:

    【解决方案2】:

    这完全取决于对浮点值可用的操作:

    • 如果您有floorceil,那么您可以使用其中之一来获得整数部分,并使用减法获得小数部分。
    • 如果您有除以余数,您可以这样做(使用 1 作为除数)。
    • 如果您可以检查值的按位表示,知道哪些位是指数和尾数,那么您可以使用它。
    • 如果您可以将值视为十进制字符串,则可以在小数点分隔符处进行拆分(通常为 .,),尽管科学计数法需要额外的工作来处理。
    • 如果您只有比较、加法和减法,那么您可以对整数部分进行二分搜索——通过一系列指数增长的猜测来确定起始界限。这可能是最“通用”的,因为它只假设有序加法组的基本数学运算(因为如果你愿意,你可以避免乘法或除法)。但是很难想象会有一种严肃的浮点编程语言不提供更有效的方法。

    【讨论】:

    • floorceil 失败,除非它们以符号为条件。例如,对于常见的double,将before = floor(x); after = x - before; 应用于 -0x1p-54 将产生 -1 和 1,此时结果应该是 0 和 -0x1p-54 或 -1 以及一个略小于 1 的不可表示值,具体取决于根据需要。使用truncfmod比较合适。
    • @EricPostpischil:同意,当然,这是给那些想要用任何特定语言编写具有这些东西的代码的人的正确建议。我只是不知道 truncmodf 是否算作“我不想要任何代码”,因为它们被专门定义为返回(其中一个)所需的值。
    • @SteveJessop:+1,但您的二分搜索可以改进。 floor(x) 必须在 (x-1, x] 范围内,所以不需要指数猜测(你会搜索什么?)。但是你怎么知道你什么时候到达了这个楼层?以及如何你找到没有乘法或除法的中点了吗?(是的,我知道 OP 想要 trunc(),而不是 floor(),但这很容易通过使用绝对值来解决。)
    • @rici:我想到的搜索只会使用整数值(尽管在例如 C 中,如果你想超越 @987654334,你需要将它们放在 double 类型中@)。当你找到一个整数值 f 这样f <= numbernumber < f + 1 时,你就知道你找到了底线。
    • @rici:哦,你可以通过知道 2 的连续幂来找到没有除法的中点(当你的猜测变大时建立一个表)。然后在二分查找的每一步中,仍然要查找的范围的长度始终是 2 的幂,因此您可以通过将下一个较小的 2 的幂加到下限来找到中点。或者只是划分,当然:我并不是说这都是一个好主意,只是说它可以作为一种智力练习来完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多