将双精度数“智能”转换为两个不同格式的字符串?
-
06-07-2019 - |
题
我正在使用一个数据库,该数据库有以下限制: 仅(数字)数据类型 它可以存储的是 双倍的. 。我想要做的是选择某一行的数字并将其放入 HTTP 请求中。问题在于我不知道这个数字是否应该有小数。
例如,如果双精度数是一个 ID,我就不能进行任何类型的格式化,因为获取 HTTP请求 会很困惑。观察以下示例:
site.com/showid.php?id=12300000 // OK
site.com/showid.php?id=1.23E7 // Bad; scientific notation
site.com/showid.php?id=12300000.0 // Bad; trailing decimal
解决这个问题的方法是 将其投射到长. 。忽略长整型溢出的问题,它解决了科学计数法和(显然)尾随小数。这可能是一个可接受的解决方案,但如果代码不假设它是我们正在处理的 ID,那就太好了。例如,如果我要查询一个显示地图且数字是坐标的网站,该怎么办? 小数在哪里非常重要? 那么长的强制转换将不再被接受。
简而言之;
- 如果 double 没有小数,则不要添加尾随小数。
- 如果有小数,则全部保留。
- 两种情况都不应该有科学记数法或千位分隔符。
该解决方案将移植到 C# 和 Java,因此我接受这两种语言的答案。(哦,我不知道该怎么称呼这个问题,如果你有更好的东西,请随意重命名。)
解决方案 6
这是我自己的结论:
- 检查 double 是否有小数。
- 根据情况,相应地格式化字符串。
然后是一些重要的事情;在没有指定不变的文化的情况下,逗号中的逗号可能是“”,而不是“”。 HTTP请求不喜欢它。当然,只有当您的操作系统设置为更喜欢逗号的区域设置时,才会出现此问题。
public static string DoubleToStringFormat(double dval) { long lval = (long)dval; if ((double)lval == dval) { // has no decimals: format as integer return dval.ToString("#.", CultureInfo.InvariantCulture); } else { // has decimals: keep them all return dval.ToString("0.##################", CultureInfo.InvariantCulture); } }
其他提示
为了补充 gustafc(他比我领先 1 分钟)的答案,这里是 C# 的相关代码行:
MyDouble.ToString("0.################")
或者
string.Format("{0:0.################}", MyDouble);
既然如果它是整数(无论它代表 ID 还是坐标),那么格式化不带尾随零的值是安全的,为什么不直接将您在要点中描述的逻辑编码化呢?例如(C#,但应该很容易转换为 Java):
// Could also use Math.Floor, etc., to determine if it is integral
long integralPart = (long)doubleValue;
if ((double)integralPart == doubleValue)
{
// has no decimals: format it as an integer e.g. integralPart.ToString("D") in C#
}
else
{
// has decimals: keep them all e.g. doubleValue.ToString("F17")
}
将数字封装在自定义类型中怎么样?
public class IntelligentNumber
{
private readonly double number;
public IntelligentNumber(double number)
{
this.number = number;
}
public override string ToString()
{
long integralPart = (long)this.number;
if((double)integralPart == this.number)
{
return integralPart.ToString();
}
else
{
return this.number.ToString();
}
}
}
另请参阅 Vilx- 的答案,了解比上面算法更好的算法。
检查 num == round(num) 是否
在 Java 中,你可以这样做 十进制格式.
static String format(double n) {
return new DecimalFormat("0.###########################").format(n);
}
这 #
除非数字不是零,否则占位符不会显示,并且小数点不会显示,除非后面有其他内容。