You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-zh@flink.apache.org by happygoing <sg...@163.com> on 2022/05/13 03:03:27 UTC

BigDecimal数据转为指定精度的DecimalData,为什么要用

Hi,All:


    使用tableEnv.createTemporaryView(String path, DataStream<T> dataStream, Schema schema)创建临时表后使用SQL查询(schema中有个字段为decimal,定义为DataTypes.DECIMAL(10,2))时。当我发送的数据小数位超过2,结果会被四舍五入,如,10.136 -> 10.14。 后面debug时发现在数据转换时,会被四舍五入。


   想咨询下:
   1、为什么要用RoundingMode.HALF_UP,是出于什么考虑?
   2、可以调整成RoundingMode.ROUND_DOWN只取固定的小数位吗?


附录:
DecimalData转换源码
/**
 * Creates an instance of {@link DecimalData} from a {@link BigDecimal} and the given precision
 * and scale.
 *
 * <p>The returned decimal value may be rounded to have the desired scale. The precision will be
 * checked. If the precision overflows, null will be returned.
 */
public static @Nullable DecimalData fromBigDecimal(BigDecimal bd, int precision, int scale) {
    bd = bd.setScale(scale, RoundingMode.HALF_UP);
    if (bd.precision() > precision) {
return null;
}

long longVal = -1;
    if (precision <= MAX_COMPACT_PRECISION) {
        longVal = bd.movePointRight(scale).longValueExact();
}
return new DecimalData(precision, scale, longVal, bd);
}

Re:BigDecimal数据转为指定精度的DecimalData,为什么要用

Posted by Xuyang <xy...@163.com>.
Hi, 我说说我的看法。<br/>第一个问题在我看来,用RoundingMode.HALF_UP更多的是和其他主流db的行为保持一致。我在mysql中试了,如果cast一个double类型的1.5到SIGNED int,会变成2。cast 1.4 as SIGNED,结果是1.<br/>第二个问题,你看下Flink函数TRUNCATE满足你的要求吗?不行的话你可以试下用udf自定义行为。
在 2022-05-13 11:03:27,"happygoing" <sg...@163.com> 写道:
>Hi,All:
>
>
>    使用tableEnv.createTemporaryView(String path, DataStream<T> dataStream, Schema schema)创建临时表后使用SQL查询(schema中有个字段为decimal,定义为DataTypes.DECIMAL(10,2))时。当我发送的数据小数位超过2,结果会被四舍五入,如,10.136 -> 10.14。 后面debug时发现在数据转换时,会被四舍五入。
>
>
>   想咨询下:
>   1、为什么要用RoundingMode.HALF_UP,是出于什么考虑?
>   2、可以调整成RoundingMode.ROUND_DOWN只取固定的小数位吗?
>
>
>附录:
>DecimalData转换源码
>/**
> * Creates an instance of {@link DecimalData} from a {@link BigDecimal} and the given precision
> * and scale.
> *
> * <p>The returned decimal value may be rounded to have the desired scale. The precision will be
> * checked. If the precision overflows, null will be returned.
> */
>public static @Nullable DecimalData fromBigDecimal(BigDecimal bd, int precision, int scale) {
>    bd = bd.setScale(scale, RoundingMode.HALF_UP);
>    if (bd.precision() > precision) {
>return null;
>}
>
>long longVal = -1;
>    if (precision <= MAX_COMPACT_PRECISION) {
>        longVal = bd.movePointRight(scale).longValueExact();
>}
>return new DecimalData(precision, scale, longVal, bd);
>}