cast from bigdecimal to bigint throws ArithmeticException

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

cast from bigdecimal to bigint throws ArithmeticException

徐涛
Hi Experts,
        There is a Flink table which has a column typed as java.math.BigDecimal, then in SQL I try to cast it to type long,
        cast(duration as bigint)

        however it throws the following exception:
java.lang.ArithmeticException: Rounding necessary
        at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4148)
        at java.math.BigDecimal.needIncrement(BigDecimal.java:4204)
        at java.math.BigDecimal.divideAndRound(BigDecimal.java:4112)
        at java.math.BigDecimal.setScale(BigDecimal.java:2452)
        at java.math.BigDecimal.longValueExact(BigDecimal.java:3090)
        at DataStreamCalcRule$45.processElement(Unknown Source)
        at org.apache.flink.table.runtime.CRowProcessRunner.processElement(CRowProcessRunner.scala:66)
        at org.apache.flink.table.runtime.CRowProcessRunner.processElement(CRowProcessRunner.scala:35)
        at org.apache.flink.streaming.api.operators.ProcessOperator.processElement(ProcessOperator.java:66)

        I wonder if it is not possible to cast java.math.BigDecimal to Long at runtime, is there anyway to achieve the cast?
        Thanks a lot !

Best
Henry
Reply | Threaded
Open this post in threaded view
|

Re: cast from bigdecimal to bigint throws ArithmeticException

Timothy Victor
This is more a Java question than Flink per se.   But I believe you need to specify the rounding mode because it is calling longValueExact.  If it just called longValue it would have worked without throwing an exception....but you risk overflowing 64 bits and getting a totally erroneous answer.

Are your values really greater than 64 bits?  If it is then the only option other than BigDecimal in Java would be BigInt.   Or you start splitting your values into 2 parts...an unscaled value and a factor such that your value is unscaledValue * 10^(-factor).

Tim

On Mon, Feb 25, 2019, 8:26 PM 徐涛 <[hidden email]> wrote:
Hi Experts,
        There is a Flink table which has a column typed as java.math.BigDecimal, then in SQL I try to cast it to type long,
        cast(duration as bigint)

        however it throws the following exception:
java.lang.ArithmeticException: Rounding necessary
        at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4148)
        at java.math.BigDecimal.needIncrement(BigDecimal.java:4204)
        at java.math.BigDecimal.divideAndRound(BigDecimal.java:4112)
        at java.math.BigDecimal.setScale(BigDecimal.java:2452)
        at java.math.BigDecimal.longValueExact(BigDecimal.java:3090)
        at DataStreamCalcRule$45.processElement(Unknown Source)
        at org.apache.flink.table.runtime.CRowProcessRunner.processElement(CRowProcessRunner.scala:66)
        at org.apache.flink.table.runtime.CRowProcessRunner.processElement(CRowProcessRunner.scala:35)
        at org.apache.flink.streaming.api.operators.ProcessOperator.processElement(ProcessOperator.java:66)

        I wonder if it is not possible to cast java.math.BigDecimal to Long at runtime, is there anyway to achieve the cast?
        Thanks a lot !

Best
Henry
Reply | Threaded
Open this post in threaded view
|

Re: Does Flink apply API for setScale of BigDecimal type

徐涛
Hi Victor,
Yeah, I think it is a Java question, but I just wonder how could set scale of BigDecimal type in Flink.
For example, I use the Types.DECIMAL type in table connector, and set the column name to A,  then I divide the column A by 1.1 in SQL. Then it will report exception then. But it seems that Flink does not apply APIs to modify the scale of the BigDecimal value.

Best
Henry

在 2019年2月26日,上午10:40,Timothy Victor <[hidden email]> 写道:

This is more a Java question than Flink per se.   But I believe you need to specify the rounding mode because it is calling longValueExact.  If it just called longValue it would have worked without throwing an exception....but you risk overflowing 64 bits and getting a totally erroneous answer.

Are your values really greater than 64 bits?  If it is then the only option other than BigDecimal in Java would be BigInt.   Or you start splitting your values into 2 parts...an unscaled value and a factor such that your value is unscaledValue * 10^(-factor).

Tim

On Mon, Feb 25, 2019, 8:26 PM 徐涛 <[hidden email]> wrote:
Hi Experts,
        There is a Flink table which has a column typed as java.math.BigDecimal, then in SQL I try to cast it to type long,
        cast(duration as bigint)

        however it throws the following exception:
java.lang.ArithmeticException: Rounding necessary
        at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4148)
        at java.math.BigDecimal.needIncrement(BigDecimal.java:4204)
        at java.math.BigDecimal.divideAndRound(BigDecimal.java:4112)
        at java.math.BigDecimal.setScale(BigDecimal.java:2452)
        at java.math.BigDecimal.longValueExact(BigDecimal.java:3090)
        at DataStreamCalcRule$45.processElement(Unknown Source)
        at org.apache.flink.table.runtime.CRowProcessRunner.processElement(CRowProcessRunner.scala:66)
        at org.apache.flink.table.runtime.CRowProcessRunner.processElement(CRowProcessRunner.scala:35)
        at org.apache.flink.streaming.api.operators.ProcessOperator.processElement(ProcessOperator.java:66)

        I wonder if it is not possible to cast java.math.BigDecimal to Long at runtime, is there anyway to achieve the cast?
        Thanks a lot !

Best
Henry