“智能”将 double 转换为两个不同格式的字符串?

发布于 2024-08-08 17:24:56 字数 783 浏览 7 评论 0原文

我正在使用的数据库有一个限制,即它可以存储的唯一(数字)数据类型双精度。我想要做的是选择某一行的数字并将其放入 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

解决此问题的方法是将其转换为 long。忽略长整型溢出的问题,它解决了科学计数法和(显然)尾随小数。这可能是一个可接受的解决方案,但如果代码不假设它是我们正在处理的 ID,那就太好了。例如,如果我要查询一个显示地图的站点,并且数字是坐标,其中小数非常重要,该怎么办?那么转换为 long 将不再被接受。

简而言之;

  • 如果 double 没有小数,则不要添加尾随小数。
  • 如果有小数,则全部保留。
  • 两种情况都不应该有科学记数法或千位分隔符。

该解决方案将移植到 C# 和 Java,因此我接受这两种语言的答案。 (哦,我不知道该怎么称呼这个问题,如果你有更好的东西,请随意重命名。)

I'm working with a database that has the limit that the only (numeric) datatype it can store is a double. What I want to do is pick the number for a certain row and put it into an HTTP request. The problem revolves around that I cannot know if this number should or should not have decimals.

For example, if the double is an ID, I cannot have any kind of formatting whatsoever, since the site that gets the HTTP request will be confused. Observe the following examples:

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

The solution to this would be to cast it to a long. Ignoring the problem of overflowing the long, it solves the scientific notation and (obviously) trailing decimal. This could be an acceptable solution but it would be nice if the code didn't assume it were IDs we were dealing with. What if, for example, I were to query a site that shows a map and the number are coordinates, where the decimals are very important? Then a cast to long is no longer acceptable.

In short;

  • If the double has no decimals, do not add a trailing decimal.
  • If it has decimals, keep them all.
  • Neither case should have scientific notation or thousand separators.

This solution will be ported to both C# and Java so I accept answers in both languages.
(Oh, and I had no idea what to call this question, feel free to rename if you got something better.)

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

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

发布评论

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

评论(6

折戟 2024-08-15 17:24:56

为了补充 gustafc 的答案(他比我领先 1 分钟),这里是 C# 的相关代码行:

MyDouble.ToString("0.################")

string.Format("{0:0.################}", MyDouble);

To complement the answer of gustafc (who beat me by 1 minute), here's the relevant code line for C#:

MyDouble.ToString("0.################")

or

string.Format("{0:0.################}", MyDouble);
深海里的那抹蓝 2024-08-15 17:24:56

既然如果它是整数(无论它代表 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")
}

Since it is safe to format the value with no trailing zeroes if it is integral (whether it represents an ID or a coordinate), why not just codify the logic you describe in your bullet points? For example (C#, but should translate readily to 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")
}
往事风中埋 2024-08-15 17:24:56

将数字封装在自定义类型中怎么样?

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- 的答案,了解比上面算法更好的算法。

How about encapsulating the number in a custom type?

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();
        }
    }
}

See also Vilx-'s answer for a better algorithm than the one above.

一个人的夜不怕黑 2024-08-15 17:24:56

检查是否 num == round(num)

check whether num == round(num)

温柔嚣张 2024-08-15 17:24:56

在 Java 中,您可以使用 DecimalFormat< /a>.

static String format(double n) { 
    return new DecimalFormat("0.###########################").format(n); 
}

# 占位符不会显示,除非数字不是零,并且小数点不会显示,除非后面有其他内容。

In Java, you can do this with DecimalFormat.

static String format(double n) { 
    return new DecimalFormat("0.###########################").format(n); 
}

The # placeholders won't show up unless the number something other than zeros to put there, and the decimal point doesn't show up unless there's something following it.

℉絮湮 2024-08-15 17:24:56

这是我自己的结论:

  • 检查双精度是否有小数。
  • 根据情况,相应地格式化字符串。
  • 然后是一些重要的事情;如果不指定不变区域性,则 has-decimals 情况下的逗号可能是“,”而不是“.”。 HTTP 请求不喜欢它。当然,只有当您的操作系统设置为更喜欢逗号的区域设置时,才会出现此问题。

    public static string DoubleToStringFormat(double dval)
    {
        长 lval = (长)dval;
        if ((双)lval == dval)
        {
            // 没有小数:格式为整数
            return dval.ToString("#.", CultureInfo.InvariantCulture);
        }
        别的
        {
            // 有小数:全部保留
            return dval.ToString("0.##################", CultureInfo.InvariantCulture);
        }
    }
    

Heres my own conclusion:

  • Check if the double has decimals.
  • Depending on that, format the string accordingly.
  • And then something important; without specifying an invariant culture, the comma in the has-decimals case may be a "," instead of a "." which isnt liked by HTTP requests. Of course, this problem only crops up if your OS is set to a locale that prefers the comma.

    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);
        }
    }
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文