如何在.NET Framework中没有科学记数法的情况下将double转换为浮点字符串表示形式?
"小"样本(有效数字可以是任何大小,例如1.5E200或1e-200):
3248971234698200000000000000000000000000000000
0.00000000000000000000000000000000000023897356978234562
Run Code Online (Sandbox Code Playgroud)
的无标准的数字格式都是这样的,和一个自定义格式也似乎并没有让小数点后具有开放位数.
这不是如何将double转换为字符串而没有10代表(E-05)的重复,因为那里给出的答案并没有解决手头的问题.这个问题中接受的解决方案是使用固定点(例如20位数),这不是我想要的.固定点格式化和修剪冗余0不能解决问题,因为固定宽度的最大宽度为99个字符.
注意:解决方案必须正确处理自定义数字格式(例如,其他小数分隔符,具体取决于区域性信息).
编辑:问题实际上只是取代前面提到的数字.我知道浮点数如何工作以及可以使用和计算哪些数字.
假设我们有一个System.Decimal数字.
为了说明,我们来看一个ToString()表示如下:
d.ToString() = "123.4500"
Run Code Online (Sandbox Code Playgroud)
关于这个十进制,可以说以下内容.对于我们这里的目的,比例定义为小数点右边的位数.有效比例相似但忽略了小数部分中出现的任何尾随零.(换句话说,这些参数定义为SQL小数加上一些额外的参数,以说明小数部分中尾随零的System.Decimal概念.)
给定一个任意的System.Decimal,如何有效地计算所有这四个参数而不转换为String并检查String?该解决方案可能需要Decimal.GetBits.
更多例子:
Examples Precision Scale EffectivePrecision EffectiveScale
0 1 (?) 0 1 (?) 0
0.0 2 (?) 1 1 (?) 0
12.45 4 2 4 2
12.4500 6 4 4 2
770 3 0 3 0
Run Code Online (Sandbox Code Playgroud)
(?)或者将这些精度解释为零也没关系.
我最近遇到了非规范化的定义,我理解有些数字不能用标准化的形式表示,因为它们太小而不适合它的相应类型.根据IEEE
所以我试图做的是当一个非规范化数字作为参数传递时捕获,以避免使用这个数字进行计算.如果我理解正确,我只需要在非规范化范围内查找数字
private bool IsDenormalizedNumber(float number)
{
return Math.Pow(2, -149) <= number && number<= ((2-Math.Pow(2,-23))*Math.Pow(2, -127)) ||
Math.Pow(-2, -149) <= number && number<= -((2 - Math.Pow(2, -23)) * Math.Pow(2, -127));
}
Run Code Online (Sandbox Code Playgroud)
我的解释是否正确?
是否有一个名为frexp的C/C++函数的Java等价物?如果您不熟悉,维基百科将frexp 定义为"将浮点数分解为尾数和指数".
我正在寻找速度和准确性的实现,但如果我只选择一个,我宁愿准确.
这是第一个参考的代码示例.它应该使frexp合约更加清晰:
/* frexp example */
#include <stdio.h>
#include <math.h>
int main ()
{
double param, result;
int n;
param = 8.0;
result = frexp (param , &n);
printf ("%lf * 2^%d = %f\n", result, n, param);
return 0;
}
/* Will produce: 0.500000 * 2^4 = 8.000000 */
Run Code Online (Sandbox Code Playgroud) 编辑:现在让它工作,同时规范化mantiss,首先设置隐含位是很重要的,当解码隐含位然后不必添加.我将标记的答案保留为正确,因为那里的信息确实有帮助.
我目前正在实现编码(专有编码规则),并且编码双值时会有轻微问题.
所以,我可以通过使用以下方式从c#中的double中取出符号,指数和尾数:
// get parts
double value = 10.0;
long bits = BitConverter.DoubleToInt64Bits(value);
// Note that the shift is sign-extended, hence the test against -1 not 1
bool negative = (bits < 0);
int exponent = (int)((bits >> 52) & 0x7ffL);
long mantissa = bits & 0xfffffffffffffL;
Run Code Online (Sandbox Code Playgroud)
(使用此处的代码).这些值可以编码,过程的简单反转将使我恢复原来的双倍.
但是,DER编码规则指定应该对尾数进行规范化:
在规范编码规则和可分辨编码规则中,规定了归一化,并且尾数(除非它是0)需要重复移位,直到最低有效位为1.
(见8.5.6.5节).
手动执行此操作:
while ((mantissa & 1) == 0)
{
mantissa >>= 1;
exponent++;
}
Run Code Online (Sandbox Code Playgroud)
不行,并给我奇怪的价值观.(即使使用Jon Skeet在上述链接中发布的整个功能).
我似乎在这里遗漏了一些东西,如果我第一次能够规范化双重的mantiassa并得到"位",那将是最简单的.但是,我也无法真正理解为什么手动标准化将无法正常工作.
谢谢你的帮助,
丹尼
编辑:实际工作问题显示我的mantiss规范化问题:
static void Main(string[] args)
{ …Run Code Online (Sandbox Code Playgroud) 数字170可以表示为归一化形式,其中:
1,7为分数系数
+2为指数,以10为基数。
170 = 1.7×10 + 2
有没有办法以数学方式提取“分数系数”?不使用字符串表示形式。
var testInputs =
new double[] {
1.7E+1, // 17
1.7E+2, // 170
1.7E+3, // 1700
-1.7E+1, // -17
-1.7E+2, // -170
-1.7E+3, // -1700
1.7E-1, // 0,17
1.7E-2, // 0,017
1.7E-3, // 0,0017
-1.7E-1, // -0,17
-1.7E-2, // -0,017
-1.7E-3, // -0,0017
};
Run Code Online (Sandbox Code Playgroud)
这些检验的分数系数的绝对值为:1,7。
Nb:,小数点分隔符。
我需要将float转换为int(单精度,32位),如:
'float:2(hex:40000000)to int:1073741824'.知道如何实现吗?
我在msdn帮助中寻找它但没有结果.