双倍到 Int,动态删除精度点 [关闭]

Double to Int with removing precision point dynamically [closed]

提问人:ibrahiem Mohamed 提问时间:8/2/2023 更新时间:8/2/2023 访问量:88

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

4个月前关闭。

在 Kotlin 或 Java 中是否有办法将 Double 解析为 Int,因为知道所有双精度都不会超过 Int 内存限制? 例子:

整数
1,123 1123
1,1 11
1,12345 11234
0,12345 1234

我知道我们可以先将其解析为字符串并删除“.”,然后解析为Int,但我想要一种更有效的方法。

Java Kotlin 精度

评论

3赞 g00se 8/2/2023
为什么 5 会消失?
4赞 aled 8/2/2023
“int memory limit”是什么意思?此外,这不是解析,而是类型转换,但数字也正在转换。1.1 不等于 11。解释预期的转换。
0赞 8/2/2023
从技术上讲,除了使用将输入转换为正则表达式和使用正则表达式之外,您没有其他方法可以实现这一点。正如@aled所指出的,你不是在解析,你是,左边在数学上与桌子的右边不相关。Stringextracting
1赞 Pshemo 8/2/2023
请注意,类型中没有 1.1 的确切值。更多信息 浮点数学坏了吗?floating-point-gui.defloating-point-gui.de/basic、docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.htmldouble
1赞 broot 8/2/2023
目前还不清楚,你指的是什么转换。我们应该转换为还是只是?另外,这是否意味着 和 ,即使它们几乎相同,也应该转换为截然不同的 和 ?另外,是否应该转换为完全相同的 int?1.100111001111.11.111111111.11.11

答:

0赞 aled 8/2/2023 #1

假设您要保留所有有效数字,您应该使用 BigDecimal 进行转换和转换,而不会丢失信息:

import java.math.BigDecimal;

public class MyClass {
    public static void main(String args[]) {
      BigDecimal x=BigDecimal.valueOf(1.12345);
      int y=x.unscaledValue().intValueExact();
      System.out.println("y = " + y);
    }
}

输出:

y = 112345

valueOf()需要从浮点类型创建 BigDecimal,而不会出现表示错误。 如果结果超出 的范围,将引发异常。intValueExact()int

请注意,此解决方案将 5 保留在数字的末尾,这与示例不同。

评论

0赞 aled 8/2/2023
你是对的。我可以替换并得到相同的结果。为了清楚起见,我会这样做。感谢您指出这一点。x.movePointRight(x.scale())x.unscaledValue()
0赞 Jean-Samuel Girard 8/2/2023 #2

如果您知道要在小数部分后保留多少位数字,则可以乘以 10^n 并将结果存储在 int 中。

使用浮点存储双精度的方式始终是数字的近似值。就像其他人说的,这意味着 1.1 不能准确表示,实际值更接近 1.100000000000000088817841970012523233890533447265625

如果我们知道您试图通过这种数据转换实现什么,也许我们可以提供不同的替代方案?因为这是一件非常奇怪的事情,我想不出为什么您需要在任何应用程序中执行此操作的原因。

0赞 DevilsHnd - 退した 8/2/2023 #3

BigDecimal 绝对是要走的路,但是,如果您想要另一种选择,您可以做这样的事情......

  • 将 double 类型值转换为字符串;
  • 删除小数点(无论它是什么类型);
  • 将字符串转换为长整型数据类型;
  • 查看 long 值是否大于或等于 Integer.MIN_VALUE 或者,小于或等于整数.MAX_VALUE。如果是,则将 long 值转换为 int。如果不是,则删除单个尾随数字 从长整型值并再次检查。继续检查,直到很久 value 位于 Integer.MIN_VALUE 和 Integer.MAX_VALUE 范围内。

下面是一个代码示例。请务必阅读评论:

/* Double type values to convert in double type array. 
   You could potentially supply signed values as well.
   The decimal point identifier can be whatever suits 
   your specific system locale (. or ,):    */
double[] dblArray = {1.1234567896543217d, 1.123d, 1.1d, 
    1.1001, -1.10017887643456776d, 1.12345d, 0.12345d, 
    87.543276d, 4657.439802};

/* Display a table header in Console for the conversion results 
   from the double type array to int values. The String.format()
   method is used:        */
System.out.println("Remove decimal point and convert to int:\n");
System.out.println(String.format("%-25s %-12s", "Double (double)", "Integer (int)"));
System.out.println("=======================================");

/* Convert each double type element within the dblArray[] array
   to int ans display the results in a Table style format:   */
boolean greaterThanMinMaxInt;   // Flag
for (Double dbl : dblArray) {
    greaterThanMinMaxInt = false; // Used only for display purposes.
    /* First convert the double type data to an long type value
       by converting the double type value to String then removing 
       the decimal point (be it '.' or ',') then using the known 
       Long.parseLong() method to convert the new string value to 
       a long data type. This is done to ensure the the double 
       value conversion will fit and we can then check for Integer
       MIN/MAX.             */
    long lng = Long.parseLong(String.valueOf(dbl).replaceAll("[.,]", ""));

    /* Is the long type value less than Integer.MIN_VALUE or greater 
       than Integer.MAX_VALUE. If it is then remove a digit from the 
       trailing end of the long type value. Keep doing this until the 
       long value falls within bounds:         */
    while (lng < Integer.MIN_VALUE || lng > Integer.MAX_VALUE) {
        lng = lng / 10; // Remove last digit in long value.
        greaterThanMinMaxInt = true; // Flag set - Value needed reducing.
    }

    /* Now that the long type value is within Integer.MIN/MAX 
       values, convert the value to `int`:   */
    int intValue = (int) lng;

    /* Display the result within Console Table. Nested Ternary 
       Operators are used to display which values were actually 
       reduced in length to satisfy Integer.MIN_VALUE and 
       Integer.MAX_VALUE:  */
    System.out.println(String.format("%-25s %-12s", String.valueOf(dbl), 
            String.valueOf(intValue) + (greaterThanMinMaxInt ? (intValue > 0 
                    ? " ('Had' Integer.MAX_VALUE Overflow)" : " ('Had' Integer.MIN_VALUE Overflow)") 
                    : "")));
}

如果运行上述代码,则应在“控制台窗口”中看到以下内容:

Remove decimal point and convert to int:

Double (double)           Integer (int)
=======================================
1.1234567896543217        1123456789 ('Had' Integer.MAX_VALUE Overflow)
1.123                     1123        
1.1                       11          
1.1001                    11001       
-1.1001788764345677       -1100178876 ('Had' Integer.MIN_VALUE Overflow)
1.12345                   112345      
0.12345                   12345       
87.543276                 87543276    
4657.439802               465743980 ('Had' Integer.MAX_VALUE Overflow)