gpt4 book ai didi

c# - 将 System.Double 表示为可排序字符串的最佳方式是什么?

转载 作者:行者123 更新时间:2023-11-30 14:39:08 24 4
gpt4 key购买 nike

在所有底层类型都是字符串的数据格式中,数字类型必须转换为可以按字母顺序比较的标准化字符串格式。例如,如果没有负数,则值 27short 可以表示为 00027

double 表示为字符串的最佳方式是什么?在我的例子中,我可以忽略负数,但我很好奇你在这两种情况下如何表示双数。

更新

根据 Jon Skeet 的建议,我现在正在使用它,尽管我不能 100% 确定它会正常工作:

static readonly string UlongFormatString = new string('0', ulong.MaxValue.ToString().Length);

public static string ToSortableString(this double n)
{
return BitConverter.ToUInt64(BitConverter.GetBytes(BitConverter.DoubleToInt64Bits(n)), 0).ToString(UlongFormatString);
}

public static double DoubleFromSortableString(this string n)
{
return BitConverter.Int64BitsToDouble(BitConverter.ToInt64(BitConverter.GetBytes(ulong.Parse(n)), 0));
}

更新 2

我已经证实了 Jon 的怀疑——使用这种方法底片不起作用。这是一些示例代码:

void Main()
{
var a = double.MaxValue;
var b = double.MaxValue/2;
var c = 0d;
var d = double.MinValue/2;
var e = double.MinValue;
Console.WriteLine(a.ToSortableString());
Console.WriteLine(b.ToSortableString());
Console.WriteLine(c.ToSortableString());
Console.WriteLine(d.ToSortableString());
Console.WriteLine(e.ToSortableString());
}

static class Test
{
static readonly string UlongFormatString = new string('0', ulong.MaxValue.ToString().Length);
public static string ToSortableString(this double n)
{
return BitConverter.ToUInt64(BitConverter.GetBytes(BitConverter.DoubleToInt64Bits(n)), 0).ToString(UlongFormatString);
}
}

产生以下输出:

09218868437227405311
09214364837600034815
00000000000000000000
18437736874454810623
18442240474082181119

显然没有按预期排序。

更新 3

下面接受的答案是正确的。谢谢大家!

最佳答案

考虑到巨大的范围(double.MaxValue 是 1.7976931348623157E+308),填充对于 double 来说可能相当尴尬。

字符串表示是否仍然必须是人类可读的,或者只是可逆的?

这提供了一个可逆的转换,导致一个相当短的字符串表示保留了字典顺序——但是它根本不明显是什么 double 值只是来自字符串。

编辑:不要单独使用BitConverter.DoubleToInt64Bits。这会反转负值的顺序。

我确定您可以使用 DoubleToInt64Bits 执行此转换,然后进行一些位操作,但遗憾的是我现在无法让它工作 ,我有三个 child 非常想去公园...


为了使一切正确排序,负数需要以补码格式而不是符号大小存储(否则负数和正数的排序顺序相反),并且需要翻转符号位(以进行负数排序小于正数)。这段代码应该可以解决问题:

static ulong EncodeDouble(double d)
{
long ieee = System.BitConverter.DoubleToInt64Bits(d);
ulong widezero = 0;
return ((ieee < 0)? widezero: ((~widezero) >> 1)) ^ (ulong)~ieee;
}

static double DecodeDouble(ulong lex)
{
ulong widezero = 0;
long ieee = (long)(((0 <= (long)lex)? widezero: ((~widezero) >> 1)) ^ ~lex);
return System.BitConverter.Int64BitsToDouble(ieee);
}

此处演示:http://ideone.com/JPNPY

这是完整的解决方案,往返于字符串:

static string EncodeDouble(double d)
{
long ieee = System.BitConverter.DoubleToInt64Bits(d);
ulong widezero = 0;
ulong lex = ((ieee < 0)? widezero: ((~widezero) >> 1)) ^ (ulong)~ieee;
return lex.ToString("X16");
}

static double DecodeDouble(string s)
{
ulong lex = ulong.Parse(s, System.Globalization.NumberStyles.AllowHexSpecifier);
ulong widezero = 0;
long ieee = (long)(((0 <= (long)lex)? widezero: ((~widezero) >> 1)) ^ ~lex);
return System.BitConverter.Int64BitsToDouble(ieee);
}

演示:http://ideone.com/pFciY

关于c# - 将 System.Double 表示为可排序字符串的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6807111/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com