| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include <gtest/gtest.h> |
| |
| #include <limits> |
| |
| #include "vec/common/arithmetic_overflow.h" |
| #include "vec/core/types.h" |
| #include "vec/io/io_helper.h" |
| |
| namespace doris::vectorized { |
| |
| struct CheckOverFlowTest : public testing::Test { |
| void SetUp() override { |
| // This function is called before each test. |
| } |
| |
| void TearDown() override { |
| // This function is called after each test. |
| } |
| |
| Int128 to_i128(std::string str) { |
| StringRef str_ref(str.data(), str.size()); |
| Int128 val; |
| EXPECT_TRUE(try_read_int_text(val, str_ref)); |
| return val; |
| }; |
| |
| wide::Int256 to_i256(std::string str) { return wide::Int256::_impl::from_str(str.c_str()); }; |
| }; |
| |
| TEST_F(CheckOverFlowTest, test_overflow_int128) { |
| { |
| Int128 a = to_i128("-15687000000000000000000"); |
| Int128 b = to_i128("11000000000000000"); |
| Int128 c; |
| EXPECT_TRUE(common::mul_overflow(a, b, c)); |
| } |
| |
| { |
| Int128 a = to_i128("-15687000000000000000000"); |
| Int128 b = to_i128("-11000000000000000"); |
| Int128 c; |
| EXPECT_TRUE(common::mul_overflow(a, b, c)); |
| } |
| |
| { |
| Int128 a = to_i128("1000"); |
| Int128 b = to_i128("12000"); |
| Int128 c; |
| EXPECT_FALSE(common::mul_overflow(a, b, c)); |
| } |
| } |
| |
| TEST_F(CheckOverFlowTest, test_overflow_int256) { |
| { |
| wide::Int256 a = |
| to_i256("-11579208923731619542357098500868790785326998466564056403945758400791"); |
| wide::Int256 b = to_i256("1157920892373161954235709850086879078532699846656405640394575"); |
| wide::Int256 c; |
| EXPECT_TRUE(common::mul_overflow(a, b, c)); |
| } |
| |
| { |
| wide::Int256 a = to_i256("-1157920892373161954235709850086879078532699846656405640394"); |
| wide::Int256 b = to_i256("-1157920892373161954235709850086879078532699846656405640394"); |
| wide::Int256 c; |
| EXPECT_TRUE(common::mul_overflow(a, b, c)); |
| } |
| |
| { |
| wide::Int256 a = to_i256("1000"); |
| wide::Int256 b = to_i256("12000"); |
| wide::Int256 c; |
| EXPECT_FALSE(common::mul_overflow(a, b, c)); |
| } |
| // max int256, 77 decimal digits: |
| // >>> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff |
| // 57896044618658097711785492504343953926634992332820282019728792003956564819967 |
| // no overflow |
| std::vector<std::tuple<std::string, std::string, std::string>> test_input_data = { |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819968", "0", |
| "0"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819968", "1", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819968"}, |
| {"57896044618658097711785492504343953926634992332820282019728792003956564819967", "0", |
| "0"}, |
| {"57896044618658097711785492504343953926634992332820282019728792003956564819967", "1", |
| "57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"57896044618658097711785492504343953926634992332820282019728792003956564819967", "-1", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819967", "0", |
| "0"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819967", "1", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819967", "-1", |
| "57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"28948022309329048855892746252171976963317496166410141009864396001978282409983", "2", |
| "57896044618658097711785492504343953926634992332820282019728792003956564819966"}, |
| {"28948022309329048855892746252171976963317496166410141009864396001978282409983", "-2", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819966"}, |
| {"-28948022309329048855892746252171976963317496166410141009864396001978282409983", "2", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819966"}, |
| {"-28948022309329048855892746252171976963317496166410141009864396001978282409983", "-2", |
| "57896044618658097711785492504343953926634992332820282019728792003956564819966"}, |
| {"28948022309329048855892746252171976963317496166410141009864396001978282409984", "-2", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819968"}, |
| {"-28948022309329048855892746252171976963317496166410141009864396001978282409984", "2", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819968"}, |
| {"9999999999999999999999999999999999999999999999999999999999999999999999999999", "2", |
| "19999999999999999999999999999999999999999999999999999999999999999999999999998"}, |
| {"9999999999999999999999999999999999999999999999999999999999999999999999999999", "-2", |
| "-19999999999999999999999999999999999999999999999999999999999999999999999999998"}, |
| {"-9999999999999999999999999999999999999999999999999999999999999999999999999999", "2", |
| "-19999999999999999999999999999999999999999999999999999999999999999999999999998"}, |
| {"-9999999999999999999999999999999999999999999999999999999999999999999999999999", "-2", |
| "19999999999999999999999999999999999999999999999999999999999999999999999999998"}, |
| {"9999999999999999999999999999999999999999999999999999999999999999999999999999", "5", |
| "49999999999999999999999999999999999999999999999999999999999999999999999999995"}, |
| {"9999999999999999999999999999999999999999999999999999999999999999999999999999", "-5", |
| "-49999999999999999999999999999999999999999999999999999999999999999999999999995"}, |
| {"-9999999999999999999999999999999999999999999999999999999999999999999999999999", "5", |
| "-49999999999999999999999999999999999999999999999999999999999999999999999999995"}, |
| {"-9999999999999999999999999999999999999999999999999999999999999999999999999999", "-5", |
| "49999999999999999999999999999999999999999999999999999999999999999999999999995"}, |
| {"5000000000000000000000000000000000000000000000000000000000000000000000000000", "2", |
| "10000000000000000000000000000000000000000000000000000000000000000000000000000"}, |
| {"5000000000000000000000000000000000000000000000000000000000000000000000000000", "-2", |
| "-10000000000000000000000000000000000000000000000000000000000000000000000000000"}, |
| {"-5000000000000000000000000000000000000000000000000000000000000000000000000000", "2", |
| "-10000000000000000000000000000000000000000000000000000000000000000000000000000"}, |
| {"-5000000000000000000000000000000000000000000000000000000000000000000000000000", "-2", |
| "10000000000000000000000000000000000000000000000000000000000000000000000000000"}, |
| {"240615969168004511545033772477625056927", "240615969168004511545033772477625056927", |
| "57896044618658097711785492504343953926579659927927152379400772292519990683329"}, |
| {"240615969168004511545033772477625056927", "-240615969168004511545033772477625056927", |
| "-57896044618658097711785492504343953926579659927927152379400772292519990683329"}, |
| {"-240615969168004511545033772477625056927", "240615969168004511545033772477625056927", |
| "-57896044618658097711785492504343953926579659927927152379400772292519990683329"}, |
| {"-240615969168004511545033772477625056927", "-240615969168004511545033772477625056927", |
| "57896044618658097711785492504343953926579659927927152379400772292519990683329"}, |
| }; |
| for (const auto& [input1, input2, expected_str] : test_input_data) { |
| // std::cout << "-------Testing multiplication: " << input1 << " * " << input2 << " = " |
| // << expected_str << std::endl; |
| wide::Int256 i1 = wide::Int256::_impl::from_str(input1.c_str()); |
| wide::Int256 i2 = wide::Int256::_impl::from_str(input2.c_str()); |
| wide::Int256 expect_result = wide::Int256::_impl::from_str(expected_str.c_str()); |
| // std::cout << "Testing multiplication as int256: " << wide::to_string(i1) << " * " |
| // << wide::to_string(i2) << " = " << wide::to_string(expect_result) << std::endl; |
| wide::Int256 mul_res = 0; |
| bool overflow = common::mul_overflow(i1, i2, mul_res); |
| EXPECT_FALSE(overflow); |
| EXPECT_EQ(mul_res, expect_result); |
| std::string str_output = wide::to_string(mul_res); |
| EXPECT_EQ(str_output, expected_str); |
| |
| overflow = common::mul_overflow(i2, i1, mul_res); |
| EXPECT_FALSE(overflow); |
| EXPECT_EQ(mul_res, expect_result); |
| str_output = wide::to_string(mul_res); |
| EXPECT_EQ(str_output, expected_str); |
| } |
| std::vector<std::tuple<std::string, std::string>> test_input_data_overflow = { |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819968", "2"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819968", |
| "-2"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819968", |
| "99999999"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819968", |
| "-99999999"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819968", |
| "57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819968", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819968", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819968"}, |
| {"57896044618658097711785492504343953926634992332820282019728792003956564819967", "2"}, |
| {"57896044618658097711785492504343953926634992332820282019728792003956564819967", "-2"}, |
| {"57896044618658097711785492504343953926634992332820282019728792003956564819967", |
| "99999999999999999999999999999999999"}, |
| {"57896044618658097711785492504343953926634992332820282019728792003956564819967", |
| "-99999999999999999999999999999999999"}, |
| {"57896044618658097711785492504343953926634992332820282019728792003956564819967", |
| "57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"57896044618658097711785492504343953926634992332820282019728792003956564819967", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819967", "2"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819967", |
| "-2"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819967", |
| "99999999999999999999999999999999999"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819967", |
| "-99999999999999999999999999999999999"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819967", |
| "57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"-57896044618658097711785492504343953926634992332820282019728792003956564819967", |
| "-57896044618658097711785492504343953926634992332820282019728792003956564819967"}, |
| {"28948022309329048855892746252171976963317496166410141009864396001978282409984", "2"}, |
| {"28948022309329048855892746252171976963317496166410141009864396001978282409984", "3"}, |
| {"-28948022309329048855892746252171976963317496166410141009864396001978282409984", "3"}, |
| {"-28948022309329048855892746252171976963317496166410141009864396001978282409984", |
| "-3"}, |
| {"-28948022309329048855892746252171976963317496166410141009864396001978282409984", |
| "-2"}, |
| {"99999999999999999999999999999999999", "999999999999999999999999999999999999999999"}, |
| {"-99999999999999999999999999999999999", "999999999999999999999999999999999999999999"}, |
| {"99999999999999999999999999999999999", "-999999999999999999999999999999999999999999"}, |
| {"-99999999999999999999999999999999999", "-999999999999999999999999999999999999999999"}, |
| }; |
| for (const auto& [input1, input2] : test_input_data_overflow) { |
| wide::Int256 i1 = wide::Int256::_impl::from_str(input1.c_str()); |
| wide::Int256 i2 = wide::Int256::_impl::from_str(input2.c_str()); |
| // wide::Int256 mul_res_direct = i1 * i2; |
| // std::cout << "multiplication res as int256: " << wide::to_string(i1) << " * " |
| // << wide::to_string(i2) << " = " << wide::to_string(mul_res_direct) << std::endl; |
| wide::Int256 mul_res; |
| bool overflow = common::mul_overflow(i1, i2, mul_res); |
| EXPECT_TRUE(overflow); |
| overflow = common::mul_overflow(i2, i1, mul_res); |
| EXPECT_TRUE(overflow); |
| } |
| } |
| |
| } // namespace doris::vectorized |