在用浮点分开时如何保持小数的准确性

发布于 2025-02-13 23:45:34 字数 399 浏览 0 评论 0原文

我正在从事一个项目,需要将一个非常大的64位值分开。我绝对不在乎整个数字结果,而只关心小数价值。问题在于,当将大除以一个小的64位double浮点值时,由于需要存储整个数字,因此我会在浮点值中散布精度。

本质上,我要做的是:

double x = long_value / double_value % 1;

但是,如果不丢失精度,long_value是。是否有一种编写此表达式的方法,以便整个数字被丢弃,并且浮点精度不会丢失?谢谢。

编辑:顺便说一句,我在这里试图投票所有这些有用的答案,但是我只是为此问题提出了这个帐户,您需要15个声誉才能投票

I am working on a project, and I need to divide a very large 64 bit long value. I absolutely do not care about the whole number result, and only care about the decimal value. The problem is that when dividing a large long with a small 64 bit double floating point value, I loose accuracy in the floating point value due to it needing to store the whole numbers.

Essentially what I am trying to do is this:

double x = long_value / double_value % 1;

but without loosing precision the larger the long_value is. Is there a way of writing this expression so that the whole numbers are discarded and floating point accuracy is not lost? Thanks.

EDIT: btw im out here trying to upvote all these helpful answers, but I just made this account for this question and you need 15 reputation to cast a vote

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

維他命╮ 2025-02-20 23:45:34

如果您的语言提供了精确的fmod实现,则可以执行类似的操作:

double rem = fmod(long_value, double_value);
return rem / double_value;

如果long_value不会精确地转换为double值,则可以拆分它分为两半,fmod单独将这些值添加在一起,并将该总和sum -double_value by double_value

如果long_valuedouble_value为负,则可能需要考虑不同的案例,具体取决于fmod的行为以及您期望的结果。

If your language provides an exact fmod implementation you can do something like this:

double rem = fmod(long_value, double_value);
return rem / double_value;

If long_value does not convert exactly to a double value, you could split it into two halves, fmod them individually, add these values together and divide that sum or sum - double_value by double_value.

If long_value or double_value is negative you may also need to consider different cases depending on how your fmod behaves and what result you expect.

苍景流年 2025-02-20 23:45:34

long_value与:

long_value = long_value - double_value * static_cast<long>(long_value / double_value);

然后您可以这样做:

double fractionalPart = static_cast<double>(long_value / double_value) % 1;

long_value is congruent to:

long_value = long_value - double_value * static_cast<long>(long_value / double_value);

Then you can do this:

double fractionalPart = static_cast<double>(long_value / double_value) % 1;
节枝 2025-02-20 23:45:34

您使用的语言是否具有大整数/大理性库?为了避免信息丢失,您必须在转换信息时将信息“分散”到更多内存中,以免失去对保留的零件。从本质上讲,这是一个大整数库为您做的。您可以使用此算法(我不知道您正在使用哪种语言,所以这只是伪代码:

// e.g. 1.5 => (3, 2)
let (numerator, denominator) = double_value.ToBigRational().NumAndDenom();

// information-preserving version of long_value / double_value
let quotient = new BigRational(num: long_value * denominator, denom: numerator);

// information-preserving version of % 1
let remainder = quotient.FractionPart();

// some information could be lost here, but we saved it for the last step
return remainder.ToDouble();

Does the language you're using have a big integer/big rational library? To avoid loss of information, you'll have to "spread out" the information across more memory while you're transforming it so you don't lose the part you're interested in preserving. This is essentially what a big integer library would do for you. You could employ this algorithm (I don't know what language you're using so this is just pseudocode:

// e.g. 1.5 => (3, 2)
let (numerator, denominator) = double_value.ToBigRational().NumAndDenom();

// information-preserving version of long_value / double_value
let quotient = new BigRational(num: long_value * denominator, denom: numerator);

// information-preserving version of % 1
let remainder = quotient.FractionPart();

// some information could be lost here, but we saved it for the last step
return remainder.ToDouble();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文