反转 long double 的指数给我一个疯狂的结果
Inverting the exponent of a long double gives me an insane result
我正在尝试反转 long double 的指数。
假设 x = 3.5e1356。我希望 x 为 3.5e-1356。
我有这个代码:
long double x = 3.5e1356L;
int exponent;
long double fraction = frexpl(x, &exponent);
// recreate number with an inverted exponent
long double newNumber = ldexpl(fraction, -exponent);
在这段代码之后,newNumber
就是1.14732677619641872902e-1357
与原号码无关
我错过了什么?
你倒转了指数,但指数一开始就不是 1356。 long double 的指数是它的 binary 指数。
您可能写了 3.5 * 10^1356,但在内部,计算机将其存储为 * 2^ 其他内容。你所做的是产生一些东西 * 2^-其他东西,而不是 3.5 * 10^-1356.*
如果您想得到 3.5 * 10^-1356,您可能需要根据以 10 为底的对数来实现它。
*frexpl 使用与您的计算机可能使用的不同的规范化约定,因此它并没有完全反转机器级指数,但它 是 反转一个二进制指数而不是你写的十进制指数。
在你们的帮助下,我创建了这段代码,它可以正常工作,但可能还可以改进...
NSInteger exponent = 0;
long double remainder = x;
// stop the loop if remainder is >= 1 and less than 10
while (!((fabsl(remainder) >= 1.0L) && (fabsl(remainder) < 10.0L))) {
remainder /= 10.0L;
exponent ++;
}
long double finalNumber = remainder * powl(10.0L, -exponent);
利用
这一事实
a * (10^n) * (10^m) = a * 10^(n+m)
如果您计算 m 使其为 -2n,您将得到:
a * (10^n) * (10^-2n) = a * 10^(n+(-2n)) = a * 10^-n
换句话说 - 只需 将原始数字乘以 10^-2n
我会尝试这样的事情:
#include <stdio.h>
#include <math.h>
int main(void) {
long double x = 8.9e-100;
long double y = 0.0;
int exp10;
if (x != 0.0)
{
exp10 = log10l(fabsl(x));
exp10 = (exp10 >= 0) ? -2*exp10 : -2*(exp10-1);
y = x * powl(10, exp10);
}
printf("%.36Le\n", x);
printf("%.36Le\n", y);
return 0;
}
3.5 * 10^12 的示例:
3.5 * 10^12 * 10^-24 --> 3.5 * 10^-12
我正在尝试反转 long double 的指数。
假设 x = 3.5e1356。我希望 x 为 3.5e-1356。
我有这个代码:
long double x = 3.5e1356L;
int exponent;
long double fraction = frexpl(x, &exponent);
// recreate number with an inverted exponent
long double newNumber = ldexpl(fraction, -exponent);
在这段代码之后,newNumber
就是1.14732677619641872902e-1357
与原号码无关
我错过了什么?
你倒转了指数,但指数一开始就不是 1356。 long double 的指数是它的 binary 指数。
您可能写了 3.5 * 10^1356,但在内部,计算机将其存储为 * 2^ 其他内容。你所做的是产生一些东西 * 2^-其他东西,而不是 3.5 * 10^-1356.*
如果您想得到 3.5 * 10^-1356,您可能需要根据以 10 为底的对数来实现它。
*frexpl 使用与您的计算机可能使用的不同的规范化约定,因此它并没有完全反转机器级指数,但它 是 反转一个二进制指数而不是你写的十进制指数。
在你们的帮助下,我创建了这段代码,它可以正常工作,但可能还可以改进...
NSInteger exponent = 0;
long double remainder = x;
// stop the loop if remainder is >= 1 and less than 10
while (!((fabsl(remainder) >= 1.0L) && (fabsl(remainder) < 10.0L))) {
remainder /= 10.0L;
exponent ++;
}
long double finalNumber = remainder * powl(10.0L, -exponent);
利用
这一事实a * (10^n) * (10^m) = a * 10^(n+m)
如果您计算 m 使其为 -2n,您将得到:
a * (10^n) * (10^-2n) = a * 10^(n+(-2n)) = a * 10^-n
换句话说 - 只需 将原始数字乘以 10^-2n
我会尝试这样的事情:
#include <stdio.h>
#include <math.h>
int main(void) {
long double x = 8.9e-100;
long double y = 0.0;
int exp10;
if (x != 0.0)
{
exp10 = log10l(fabsl(x));
exp10 = (exp10 >= 0) ? -2*exp10 : -2*(exp10-1);
y = x * powl(10, exp10);
}
printf("%.36Le\n", x);
printf("%.36Le\n", y);
return 0;
}
3.5 * 10^12 的示例:
3.5 * 10^12 * 10^-24 --> 3.5 * 10^-12