Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quickly detects that BigDecimal is integer #388

Merged

Conversation

fengyizhu
Copy link

@fengyizhu fengyizhu commented Nov 15, 2022

package com;

import tech.units.indriya.function.DefaultNumberSystem;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicInteger;

package com.ke.nervecenter.type.pojos;

import tech.units.indriya.function.DefaultNumberSystem;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicInteger;

public class TryCatchTest {

    public static void main(String[] args) {

        BigDecimal bigDecimal = new BigDecimal("3.1415926");
        DefaultNumberSystem defaultNumberSystem = new DefaultNumberSystem();
        
        long start = System.currentTimeMillis();
        for (int i=0;i<100000;i++){
            Number a = defaultNumberSystem.narrow(bigDecimal);
        }
        long end = System.currentTimeMillis() - start;
        System.out.println("default narrow time:" + end + " ms");

        start = System.currentTimeMillis();
        for (int i=0;i<100000;i++){
            Number a = quicklyNarrow(bigDecimal);
        }
        end = System.currentTimeMillis() - start;
        System.out.println("quickly narrow time:" + end + " ms");
    }
    private static Number quicklyNarrow(Number number){
        if(number instanceof Integer || number instanceof AtomicInteger ||
                number instanceof Short || number instanceof Byte) {
            return number;
        }
        if(number instanceof BigDecimal) {

            final BigDecimal decimal = ((BigDecimal) number);
            
            if( decimal.scale() <= 0){
                try {
                    BigInteger integer = decimal.toBigIntegerExact();
                    return quicklyNarrow(integer);
                } catch (ArithmeticException e) {
                    return number; // cannot narrow to integer
                }
            }
        }
        return number;
    }
}

console

default narrow time:107 ms
quickly narrow time:1 ms

This change is Reviewable

@andi-huber
Copy link
Member

andi-huber commented Nov 15, 2022

Certainly an option, thanks for that. We might be even able to avoid the try catch clause entirely. There are some interesting answers to the question on how to check whether a BigDecimal represents an integer:
https://stackoverflow.com/questions/1078953/check-if-bigdecimal-is-an-integer-in-java

That said, I see no issue with your solution.

@andi-huber andi-huber merged commit 10dbe18 into unitsofmeasurement:master Nov 15, 2022
keilw added a commit that referenced this pull request Dec 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants