如何快速检查是否适合浮动? (JAVA) [英] How quickly check whether double fits in float? (Java)

查看:140
本文介绍了如何快速检查是否适合浮动? (JAVA)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一些算术运算或按位运算可以检查
double是否适合浮点数而不会损失
的精度。



不仅检查浮点范围内的双倍范围是
,而且尾数b $ b也不会丢失。

再见



PS:这回答了C#的一半问题:
如何检查一个double是否可以放入一个float而不会转换为无穷大
但是我需要一个适用于Java的解决方案。

解决方案

一个简单的解决方案可能如下所示:

  public class Scribble {
public static void main(String [] args){
for(int i = 1; i <= 10; i ++){

double d = 1d /((double)i);
float f =(float)d;

布尔型lossless = d == f;

System.out.println(d +可以转换+(无损?无损:只有损失));





输出:

  1.0可以转换无损
0.5可以转换无损
0.3333333333333333只能转换损失
0.25可转换无损
0.2可转换仅损失
0.16666666666666666可转换仅损失
0.14285714285714285只能转换损失
0.125可转换无损
0.1111111111111111只能转换亏损
0.1只能转亏损






编辑:速度比较显示,方法2似乎是最快的:

  method1 | method2 | method3 
237094654 | 209365345 | 468025911
214129288 | 209917275 | 448695709
232093486 | 197637245 | 448153336
249210162 | 200163771 | 460200921
240685446 | 200638561 | 447061763
332890287 | 337870633 | 450452194
247054322 | 199045232 | 449442540
235533069 | 200767924 | 452743201
256274670 | 199153775 | 453373979
298277375 | 198659529 | 456672251
229360115 | 205883096 | 454198291
252680123 | 224850463 | 452860277
246047739 | 200070587 | 458091501
304270790 | 204517093 | 463688631
235058620 | 204675812 | 448639390
260565871 | 205834286 | 458372075
256008432 | 242574024 | 498943242
311210028 | 208080237 | 478777466
242014926 | 208995343 | 457901380
239893559 | 205111348 | 451616471

code:

  public class Scribble {

static int size = 1024 * 1024 * 100;
static boolean [] results = new boolean [size];
static double [] values = new double [size];
$ b $ public static void main(String [] args){

//生成值
(int i = 0; i< size; i ++)
值[i] = 1d /((double)i);

开始;长
;

System.out.println(method1 | method2 | method3);
for(int i = 0; i <20; i ++){
start = System.nanoTime();
method1(size);
duration = System.nanoTime() - 开始;
System.out.printf(%9d,duration);

start = System.nanoTime();
method2(size);
duration = System.nanoTime() - 开始;
System.out.printf(|%9d,duration);

start = System.nanoTime();
method3(size);
duration = System.nanoTime() - 开始;
System.out.printf(|%9d \\\
,duration);



private static void method1(int size){
boolean [] results = new boolean [size];
for(int i = 0; i< size; i ++){
double d = values [i];
float f =(float)d;

布尔型lossless = d == f;
results [i] =无损;



private static void method2(int size){
for(int i = 0; i< size; i ++){
double d = values [i];
results [i] = d ==(double)(float)d;



private static void method3(int size){
for(int i = 0; i< size; i ++){
double d = values [i];
results [i] = Double.compare(d,(float)d)== 0;
}
}
}


Are there some arithmetic or bitwise operations that can check whether a double fits into a float without loss of precision.

It should not only check that the double range is in the float range, but also that no mantissa bits get lost.

Bye

P.S.: This answers the problem half way for C#: How to check if a double can fit into a float without conversion to infinity But I need a solution that works for Java.

解决方案

A straight-forward solution could look like this:

public class Scribble {
    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {

            double d = 1d / ((double)i);
            float f = (float) d;

            boolean lossless = d == f;

            System.out.println(d + " can be converted " + (lossless ? "lossless" : "only with loss"));
        }
    }
}

it outputs:

1.0 can be converted lossless
0.5 can be converted lossless
0.3333333333333333 can be converted only with loss
0.25 can be converted lossless
0.2 can be converted only with loss
0.16666666666666666 can be converted only with loss
0.14285714285714285 can be converted only with loss
0.125 can be converted lossless
0.1111111111111111 can be converted only with loss
0.1 can be converted only with loss


edit: speed comparison shows, that method2 seems to be fastest:

 method1  |  method2  |  method3 
237094654 | 209365345 | 468025911
214129288 | 209917275 | 448695709
232093486 | 197637245 | 448153336
249210162 | 200163771 | 460200921
240685446 | 200638561 | 447061763
332890287 | 337870633 | 450452194
247054322 | 199045232 | 449442540
235533069 | 200767924 | 452743201
256274670 | 199153775 | 453373979
298277375 | 198659529 | 456672251
229360115 | 205883096 | 454198291
252680123 | 224850463 | 452860277
246047739 | 200070587 | 458091501
304270790 | 204517093 | 463688631
235058620 | 204675812 | 448639390
260565871 | 205834286 | 458372075
256008432 | 242574024 | 498943242
311210028 | 208080237 | 478777466
242014926 | 208995343 | 457901380
239893559 | 205111348 | 451616471

code:

public class Scribble {

    static int size = 1024*1024*100;
    static boolean[] results = new boolean[size];
    static double[] values = new double[size];

    public static void main(String[] args) {

        // generate values
        for (int i = 0; i < size; i++)
            values[i] = 1d / ((double)i);

        long start;
        long duration;

        System.out.println(" method1  |  method2  |  method3 ");
        for (int i = 0; i < 20; i++) {
            start = System.nanoTime();
            method1(size);
            duration = System.nanoTime() - start;
            System.out.printf("%9d", duration);

            start = System.nanoTime();
            method2(size);
            duration = System.nanoTime() - start;
            System.out.printf(" | %9d", duration);

            start = System.nanoTime();
            method3(size);
            duration = System.nanoTime() - start;
            System.out.printf(" | %9d\n", duration);
        }
    }

    private static void method1(int size) {
        boolean[] results = new boolean[size];
        for (int i = 0; i < size; i++) {
            double d = values[i];
            float f = (float) d;

            boolean lossless = d == f;
            results[i] = lossless;
        }
    }

    private static void method2(int size) {
        for (int i = 0; i < size; i++) {
            double d = values[i];
            results[i] = d == (double)(float)d;
        }
    }

    private static void method3(int size) {
        for (int i = 0; i < size; i++) {
            double d = values[i];
            results[i] = Double.compare(d, (float) d) == 0;
        }
    }
}

这篇关于如何快速检查是否适合浮动? (JAVA)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆