Home > Enterprise >  Bigquery subtraction on very large number not working as expected
Bigquery subtraction on very large number not working as expected

Time:12-02

Why is this piece of SQL not giving the expected answer when subtracting.

select '2^63 - 1', cast(power(2, 63) - 1 as bignumeric) union all
select '2^63', cast(power(2, 63) as bignumeric) union all
select '2^63 with diff of 10k', cast(power(2, 63) as bignumeric) - cast(power(2, 63) - 10000 as bignumeric) union all
select '2^64 - 1', cast(power(2, 64) - 1 as bignumeric) union all
select '2^64', cast(power(2, 64) as bignumeric) union all
select '2^64 - 10000', cast(power(2, 64) - 10000 as bignumeric) union all
select '2^64 with diff of 10k', cast(power(2, 64) as bignumeric) - cast(power(2, 64) - 10000 as bignumeric)

It gives the following result. What am I missing here?

enter image description here

CodePudding user response:

POW function has its own rules for the return types:

https://cloud.google.com/bigquery/docs/reference/standard-sql/mathematical_functions#pow

You need to take these rules into account to perform precise calculations.

Let's take your first operation and inspect the return type. You can do it by creating a view, then you can inspect the column datatype.

First, let's take the power operation only:

create or replace view `qwiklabs-gcp-03-0ffb72b5a6c1.data.testview`
as select power(2, 63) as one

The return datatype is FLOAT

Second, let's add the substraction operation:

create or replace view `qwiklabs-gcp-03-0ffb72b5a6c1.data.testview`
as select power(2, 63) - 1 as one

The return type is still FLOAT.

Let's add the CAST operation now:

create or replace view `qwiklabs-gcp-03-0ffb72b5a6c1.data.testview`
as select cast(power(2, 63) - 1 as bignumeric) as one

The column datatype is BIGNUMERIC, as expected. Casting from FLOAT.

So, in order to see the right results you need to check the return types.

Let's fix that first operation following the docs:

create or replace view `qwiklabs-gcp-03-0ffb72b5a6c1.data.testview`
as select power(cast(2 as bignumeric), cast(63 as bignumeric)) - 1 as one

This way, we are providing two BIGNUMERIC and we should expect a BIGNUMERIC, that can be decrease by one.

Now, if you execute the SELECT query, the response is OK:

select * from `qwiklabs-gcp-03-0ffb72b5a6c1.data.testview`

Result: 9223372036854775807

So, please, take into account the return types and set them properly to do all the calculations.

  • Related