| /* |
| * 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 <iostream> |
| #include "gtest/gtest.h" |
| #include "storage/format/orc/int128.h" |
| |
| namespace orc { |
| |
| TEST(Int128, simpleTest) { |
| Int128 x = 12; |
| Int128 y = 13; |
| x += y; |
| EXPECT_EQ(25, x.toLong()); |
| EXPECT_EQ("0x00000000000000000000000000000019", x.toHexString()); |
| y -= 1; |
| EXPECT_EQ("0x0000000000000000000000000000000c", y.toHexString()); |
| EXPECT_EQ(12, y.toLong()); |
| EXPECT_EQ(0, y.getHighBits()); |
| EXPECT_EQ(12, y.getLowBits()); |
| y -= 20; |
| EXPECT_EQ("0xfffffffffffffffffffffffffffffff8", y.toHexString()); |
| EXPECT_EQ(-8, y.toLong()); |
| EXPECT_EQ(-1, y.getHighBits()); |
| EXPECT_EQ(static_cast<uint64_t>(-8), y.getLowBits()); |
| Int128 z; |
| EXPECT_EQ(0, z.toLong()); |
| } |
| |
| TEST(Int128, testNegate) { |
| Int128 n = -1000000000000; |
| EXPECT_EQ("0xffffffffffffffffffffff172b5af000", n.toHexString()); |
| n.negate(); |
| EXPECT_EQ(1000000000000, n.toLong()); |
| n.abs(); |
| EXPECT_EQ(1000000000000, n.toLong()); |
| n.negate(); |
| EXPECT_EQ(-1000000000000, n.toLong()); |
| n.abs(); |
| EXPECT_EQ(1000000000000, n.toLong()); |
| |
| Int128 big(0x12345678, 0x9abcdef0); |
| EXPECT_EQ("0x0000000012345678000000009abcdef0", big.toHexString()); |
| EXPECT_EQ(305419896, big.getHighBits()); |
| EXPECT_EQ(2596069104, big.getLowBits()); |
| big.negate(); |
| EXPECT_EQ("0xffffffffedcba987ffffffff65432110", big.toHexString()); |
| EXPECT_EQ(0xffffffffedcba987, big.getHighBits()); |
| EXPECT_EQ(0xffffffff65432110, big.getLowBits()); |
| big.negate(); |
| EXPECT_EQ("0x0000000012345678000000009abcdef0", big.toHexString()); |
| big.invert(); |
| EXPECT_EQ("0xffffffffedcba987ffffffff6543210f", big.toHexString()); |
| big.invert(); |
| EXPECT_EQ("0x0000000012345678000000009abcdef0", big.toHexString()); |
| } |
| |
| TEST(Int128, testPlus) { |
| Int128 n(0x1000, 0xfffffffffffffff0); |
| EXPECT_EQ("0x0000000000001000fffffffffffffff0", n.toHexString()); |
| n += 0x20; |
| EXPECT_EQ("0x00000000000010010000000000000010", n.toHexString()); |
| n -= 0x20; |
| EXPECT_EQ("0x0000000000001000fffffffffffffff0", n.toHexString()); |
| n += Int128(2, 3); |
| EXPECT_EQ("0x0000000000001002fffffffffffffff3", n.toHexString()); |
| |
| Int128 x(static_cast<int64_t>(0xffffffffffffff00), 0x200); |
| EXPECT_EQ("0xffffffffffffff000000000000000200", x.toHexString()); |
| x -= 0x300; |
| EXPECT_EQ("0xfffffffffffffeffffffffffffffff00", x.toHexString()); |
| x -= 0x100; |
| EXPECT_EQ("0xfffffffffffffefffffffffffffffe00", x.toHexString()); |
| x += 0x400; |
| EXPECT_EQ("0xffffffffffffff000000000000000200", x.toHexString()); |
| x -= Int128(1, 2); |
| EXPECT_EQ("0xfffffffffffffeff00000000000001fe", x.toHexString()); |
| } |
| |
| TEST(Int128, testLogic) { |
| Int128 n = Int128(0x00000000100000002, 0x0000000400000008); |
| n |= Int128(0x0000001000000020, 0x0000004000000080); |
| EXPECT_EQ("0x00000011000000220000004400000088", n.toHexString()); |
| n = Int128(0x0000111100002222, 0x0000333300004444); |
| n &= Int128(0x0000f00000000f00, 0x000000f00000000f); |
| EXPECT_EQ("0x00001000000002000000003000000004", n.toHexString()); |
| } |
| |
| TEST(Int128, testShift) { |
| Int128 n(0x123456789abcdef0, 0xfedcba9876543210); |
| EXPECT_EQ("0x123456789abcdef0fedcba9876543210", n.toHexString()); |
| n <<= 0; |
| EXPECT_EQ("0x123456789abcdef0fedcba9876543210", n.toHexString()); |
| n <<= 4; |
| EXPECT_EQ("0x23456789abcdef0fedcba98765432100", n.toHexString()); |
| n <<= 8; |
| EXPECT_EQ("0x456789abcdef0fedcba9876543210000", n.toHexString()); |
| n += 0x99; |
| EXPECT_EQ("0x456789abcdef0fedcba9876543210099", n.toHexString()); |
| n <<= 64; |
| EXPECT_EQ("0xcba98765432100990000000000000000", n.toHexString()); |
| n += 0x312; |
| EXPECT_EQ("0xcba98765432100990000000000000312", n.toHexString()); |
| n <<= 120; |
| EXPECT_EQ("0x12000000000000000000000000000000", n.toHexString()); |
| n += 0x411; |
| EXPECT_EQ("0x12000000000000000000000000000411", n.toHexString()); |
| n <<= 128; |
| EXPECT_EQ(0, n.toLong()); |
| |
| n = Int128(0x123456789abcdef0, 0xfedcba9876543210); |
| EXPECT_EQ("0x123456789abcdef0fedcba9876543210", n.toHexString()); |
| n >>= 0; |
| EXPECT_EQ("0x123456789abcdef0fedcba9876543210", n.toHexString()); |
| n >>= 4; |
| EXPECT_EQ("0x0123456789abcdef0fedcba987654321", n.toHexString()); |
| n >>= 8; |
| EXPECT_EQ("0x000123456789abcdef0fedcba9876543", n.toHexString()); |
| n += Int128(0x2400000000000000, 0x0); |
| EXPECT_EQ("0x240123456789abcdef0fedcba9876543", n.toHexString()); |
| n >>= 64; |
| EXPECT_EQ("0x0000000000000000240123456789abcd", n.toHexString()); |
| n += Int128(0x2400000000000000, 0x0); |
| EXPECT_EQ("0x2400000000000000240123456789abcd", n.toHexString()); |
| n >>= 129; |
| EXPECT_EQ(0, n.toLong()); |
| n = Int128(static_cast<int64_t>(0xfedcba0987654321), 0x1234567890abcdef); |
| EXPECT_EQ("0xfedcba09876543211234567890abcdef", n.toHexString()); |
| n >>= 64; |
| EXPECT_EQ("0xfffffffffffffffffedcba0987654321", n.toHexString()); |
| n = Int128(static_cast<int64_t>(0xfedcba0987654321), 0x1234567890abcdef); |
| n >>= 129; |
| EXPECT_EQ("0xffffffffffffffffffffffffffffffff", n.toHexString()); |
| n = Int128(-1, 0xffffffffffffffff); |
| n >>= 4; |
| EXPECT_EQ("0x0fffffffffffffffffffffffffffffff", n.toHexString()); |
| n = Int128(-0x100, 0xffffffffffffffff); |
| n >>= 68; |
| EXPECT_EQ("0xfffffffffffffffffffffffffffffff0", n.toHexString()); |
| } |
| |
| TEST(Int128, testCompare) { |
| Int128 x = 123; |
| EXPECT_EQ(Int128(123), x); |
| EXPECT_EQ(true, x == 123); |
| EXPECT_EQ(true, !(x == 124)); |
| EXPECT_EQ(true, !(x == -124)); |
| EXPECT_EQ(true, !(x == Int128(2, 123))); |
| EXPECT_EQ(true, !(x != 123)); |
| EXPECT_EQ(true, x != -123); |
| EXPECT_EQ(true, x != 124); |
| EXPECT_EQ(true, x != Int128(-1, 123)); |
| x = Int128(0x123, 0x456); |
| EXPECT_EQ(true, !(x < Int128(0x123, 0x455))); |
| EXPECT_EQ(true, !(x < Int128(0x123, 0x456))); |
| EXPECT_EQ(true, x < Int128(0x123, 0x457)); |
| EXPECT_EQ(true, !(x < Int128(0x122, 0x456))); |
| EXPECT_EQ(true, x < Int128(0x124, 0x456)); |
| |
| EXPECT_EQ(true, !(x <= Int128(0x123, 0x455))); |
| EXPECT_EQ(true, x <= Int128(0x123, 0x456)); |
| EXPECT_EQ(true, x <= Int128(0x123, 0x457)); |
| EXPECT_EQ(true, !(x <= Int128(0x122, 0x456))); |
| EXPECT_EQ(true, x <= Int128(0x124, 0x456)); |
| |
| EXPECT_EQ(true, x > Int128(0x123, 0x455)); |
| EXPECT_EQ(true, !(x > Int128(0x123, 0x456))); |
| EXPECT_EQ(true, !(x > Int128(0x123, 0x457))); |
| EXPECT_EQ(true, x > Int128(0x122, 0x456)); |
| EXPECT_EQ(true, !(x > Int128(0x124, 0x456))); |
| |
| EXPECT_EQ(true, x >= Int128(0x123, 0x455)); |
| EXPECT_EQ(true, x >= Int128(0x123, 0x456)); |
| EXPECT_EQ(true, !(x >= Int128(0x123, 0x457))); |
| EXPECT_EQ(true, x >= Int128(0x122, 0x456)); |
| EXPECT_EQ(true, !(x >= Int128(0x124, 0x456))); |
| |
| EXPECT_EQ(true, Int128(-3) < Int128(-2)); |
| EXPECT_EQ(true, Int128(-3) < Int128(0)); |
| EXPECT_EQ(true, Int128(-3) < Int128(3)); |
| EXPECT_EQ(true, Int128(0) < Int128(5)); |
| EXPECT_EQ(true, Int128::minimumValue() < 0); |
| EXPECT_EQ(true, Int128(0) < Int128::maximumValue()); |
| EXPECT_EQ(true, Int128::minimumValue() < Int128::maximumValue()); |
| } |
| |
| TEST(Int128, testHash) { |
| EXPECT_EQ(0, Int128().hash()); |
| EXPECT_EQ(0x123, Int128(0x123).hash()); |
| EXPECT_EQ(0xc3c3c3c3, Int128(0x0101010102020202, 0x4040404080808080).hash()); |
| EXPECT_EQ(0x122, Int128(-0x123).hash()); |
| EXPECT_EQ(0x12345678, Int128(0x1234567800000000, 0x0).hash()); |
| EXPECT_EQ(0x12345678, Int128(0x12345678, 0x0).hash()); |
| EXPECT_EQ(0x12345678, Int128(0x0, 0x1234567800000000).hash()); |
| EXPECT_EQ(0x12345678, Int128(0x0, 0x12345678).hash()); |
| } |
| |
| TEST(Int128, testFitsInLong) { |
| EXPECT_EQ(true, Int128(0x0, 0x7fffffffffffffff).fitsInLong()); |
| EXPECT_EQ(true, !Int128(0x0, 0x8000000000000000).fitsInLong()); |
| EXPECT_EQ(true, !Int128(-1, 0x7fffffffffffffff).fitsInLong()); |
| EXPECT_EQ(true, Int128(-1, 0x8000000000000000).fitsInLong()); |
| EXPECT_EQ(true, !Int128(1, 0x8000000000000000).fitsInLong()); |
| EXPECT_EQ(true, !Int128(1, 0x7fffffffffffffff).fitsInLong()); |
| EXPECT_EQ(true, !Int128(-2, 0x8000000000000000).fitsInLong()); |
| EXPECT_EQ(true, !Int128(-2, 0x7fffffffffffffff).fitsInLong()); |
| |
| EXPECT_EQ(0x7fffffffffffffff, Int128(0x0, 0x7fffffffffffffff).toLong()); |
| EXPECT_THROW(Int128(1, 1).toLong(), std::runtime_error); |
| EXPECT_EQ(0x8000000000000000, Int128(-1, 0x8000000000000000).toLong()); |
| } |
| |
| TEST(Int128, testMultiply) { |
| Int128 x = 2; |
| x *= 3; |
| EXPECT_EQ(6, x.toLong()); |
| x *= -4; |
| EXPECT_EQ(-24, x.toLong()); |
| x *= 5; |
| EXPECT_EQ(-120, x.toLong()); |
| x *= -7; |
| EXPECT_EQ(840, x.toLong()); |
| x = Int128(0x0123456776543210, 0x1111222233334444); |
| x *= 2; |
| EXPECT_EQ(0x02468aceeca86420, x.getHighBits()); |
| EXPECT_EQ(0x2222444466668888, x.getLowBits()); |
| |
| x = Int128(0x0534AB4C, 0x59D109ADF9892FCA); |
| x *= Int128(0, 0x9033b8c7a); |
| EXPECT_EQ("0x2eead9afd0c6e0e929c18da753113e44", x.toHexString()); |
| } |
| |
| TEST(Int128, testMultiplyInt) { |
| Int128 x = 2; |
| x *= 1; |
| EXPECT_EQ(2, x.toLong()); |
| x *= 2; |
| EXPECT_EQ(4, x.toLong()); |
| |
| x = 5; |
| x *= 6432346; |
| EXPECT_EQ(6432346 * 5, x.toLong()); |
| |
| x = (1LL << 62) + (3LL << 34) + 3LL; |
| x *= 96; |
| EXPECT_EQ("0x00000000000000180000048000000120", x.toHexString()); |
| |
| x = 1; |
| x <<= 126; |
| EXPECT_EQ("0x40000000000000000000000000000000", x.toHexString()); |
| x *= 2; |
| EXPECT_EQ("0x80000000000000000000000000000000", x.toHexString()); |
| x *= 2; |
| EXPECT_EQ("0x00000000000000000000000000000000", x.toHexString()); |
| } |
| |
| TEST(Int128, testFillInArray) { |
| Int128 x(0x123456789abcdef0, 0x23456789abcdef01); |
| uint32_t array[4]; |
| bool wasNegative; |
| EXPECT_EQ(4, x.fillInArray(array, wasNegative)); |
| EXPECT_EQ(true, !wasNegative); |
| EXPECT_EQ(0x12345678, array[0]); |
| EXPECT_EQ(0x9abcdef0, array[1]); |
| EXPECT_EQ(0x23456789, array[2]); |
| EXPECT_EQ(0xabcdef01, array[3]); |
| |
| x = 0; |
| EXPECT_EQ(0, x.fillInArray(array, wasNegative)); |
| EXPECT_EQ(true, !wasNegative); |
| |
| x = 1; |
| EXPECT_EQ(1, x.fillInArray(array, wasNegative)); |
| EXPECT_EQ(true, !wasNegative); |
| EXPECT_EQ(1, array[0]); |
| |
| x = -12345; |
| EXPECT_EQ(1, x.fillInArray(array, wasNegative)); |
| EXPECT_EQ(true, wasNegative); |
| EXPECT_EQ(12345, array[0]); |
| |
| x = 0x80000000; |
| EXPECT_EQ(1, x.fillInArray(array, wasNegative)); |
| EXPECT_EQ(true, !wasNegative); |
| EXPECT_EQ(0x80000000, array[0]); |
| |
| x = Int128(0, 0x8000000000000000); |
| EXPECT_EQ(2, x.fillInArray(array, wasNegative)); |
| EXPECT_EQ(true, !wasNegative); |
| EXPECT_EQ(0x80000000, array[0]); |
| EXPECT_EQ(0x0, array[1]); |
| |
| x = Int128(0x80000000, 0x123456789abcdef0); |
| EXPECT_EQ(3, x.fillInArray(array, wasNegative)); |
| EXPECT_EQ(true, !wasNegative); |
| EXPECT_EQ(0x80000000, array[0]); |
| EXPECT_EQ(0x12345678, array[1]); |
| EXPECT_EQ(0x9abcdef0, array[2]); |
| } |
| |
| int64_t fls(uint32_t x); |
| |
| TEST(Int128, testFindLastSet) { |
| EXPECT_EQ(0, fls(0)); |
| EXPECT_EQ(1, fls(1)); |
| EXPECT_EQ(8, fls(0xff)); |
| EXPECT_EQ(9, fls(0x100)); |
| EXPECT_EQ(29, fls(0x12345678)); |
| EXPECT_EQ(31, fls(0x40000000)); |
| EXPECT_EQ(32, fls(0x80000000)); |
| } |
| |
| void shiftArrayLeft(uint32_t* array, int64_t length, int64_t bits); |
| |
| TEST(Int128, testShiftArrayLeft) { |
| uint32_t array[5]; |
| // make sure nothing blows up |
| array[0] = 0x12345678; |
| shiftArrayLeft(0, 0, 30); |
| EXPECT_EQ(0x12345678, array[0]); |
| |
| array[0] = 0x12345678; |
| shiftArrayLeft(array, 1, 0); |
| EXPECT_EQ(0x12345678, array[0]); |
| |
| array[0] = 0x12345678; |
| array[1] = 0x9abcdef0; |
| shiftArrayLeft(array, 1, 3); |
| EXPECT_EQ(0x91a2b3c0, array[0]); |
| EXPECT_EQ(0x9abcdef0, array[1]); |
| |
| array[0] = 0x12345678; |
| array[1] = 0x9abcdeff; |
| array[2] = 0xfedcba98; |
| array[3] = 0x76543210; |
| shiftArrayLeft(array, 4, 4); |
| EXPECT_EQ(0x23456789, array[0]); |
| EXPECT_EQ(0xabcdefff, array[1]); |
| EXPECT_EQ(0xedcba987, array[2]); |
| EXPECT_EQ(0x65432100, array[3]); |
| |
| array[0] = 0; |
| array[1] = 0x12345678; |
| array[2] = 0x9abcdeff; |
| array[3] = 0xfedcba98; |
| array[4] = 0x76543210; |
| shiftArrayLeft(array, 5, 8); |
| EXPECT_EQ(0x00000012, array[0]); |
| EXPECT_EQ(0x3456789a, array[1]); |
| EXPECT_EQ(0xbcdefffe, array[2]); |
| EXPECT_EQ(0xdcba9876, array[3]); |
| EXPECT_EQ(0x54321000, array[4]); |
| } |
| |
| void shiftArrayRight(uint32_t* array, int64_t length, int64_t bits); |
| |
| TEST(Int128, testShiftArrayRight) { |
| uint32_t array[4]; |
| // make sure nothing blows up |
| array[0] = 0x12345678; |
| shiftArrayRight(0, 0, 30); |
| EXPECT_EQ(0x12345678, array[0]); |
| |
| array[0] = 0x12345678; |
| array[1] = 0x9abcdef0; |
| shiftArrayRight(array, 1, 3); |
| EXPECT_EQ(0x2468acf, array[0]); |
| EXPECT_EQ(0x9abcdef0, array[1]); |
| |
| array[0] = 0x12345678; |
| array[1] = 0x9abcdeff; |
| array[2] = 0xfedcba98; |
| array[3] = 0x76543210; |
| shiftArrayRight(array, 4, 4); |
| EXPECT_EQ(0x01234567, array[0]); |
| EXPECT_EQ(0x89abcdef, array[1]); |
| EXPECT_EQ(0xffedcba9, array[2]); |
| EXPECT_EQ(0x87654321, array[3]); |
| } |
| |
| void fixDivisionSigns(Int128& result, Int128& remainder, |
| bool dividendWasNegative, bool divisorWasNegative); |
| |
| TEST(Int128, testFixDivisionSigns) { |
| Int128 x = 123; |
| Int128 y = 456; |
| fixDivisionSigns(x, y, false, false); |
| EXPECT_EQ(123, x.toLong()); |
| EXPECT_EQ(456, y.toLong()); |
| |
| x = 123; |
| y = 456; |
| fixDivisionSigns(x, y, false, true); |
| EXPECT_EQ(-123, x.toLong()); |
| EXPECT_EQ(456, y.toLong()); |
| |
| x = 123; |
| y = 456; |
| fixDivisionSigns(x, y, true, false); |
| EXPECT_EQ(-123, x.toLong()); |
| EXPECT_EQ(-456, y.toLong()); |
| |
| x = 123; |
| y = 456; |
| fixDivisionSigns(x, y, true, true); |
| EXPECT_EQ(123, x.toLong()); |
| EXPECT_EQ(-456, y.toLong()); |
| } |
| |
| void buildFromArray(Int128& value, uint32_t* array, int64_t length); |
| |
| TEST(Int128, testBuildFromArray) { |
| Int128 result; |
| uint32_t array[5] = {0x12345678, 0x9abcdef0, 0xfedcba98, 0x76543210, 0}; |
| |
| buildFromArray(result, array, 0); |
| EXPECT_EQ(0, result.toLong()); |
| |
| buildFromArray(result, array, 1); |
| EXPECT_EQ(0x12345678, result.toLong()); |
| |
| buildFromArray(result, array, 2); |
| EXPECT_EQ(0x123456789abcdef0, result.toLong()); |
| |
| buildFromArray(result, array, 3); |
| EXPECT_EQ("0x00000000123456789abcdef0fedcba98", result.toHexString()); |
| |
| buildFromArray(result, array, 4); |
| EXPECT_EQ("0x123456789abcdef0fedcba9876543210", result.toHexString()); |
| |
| EXPECT_THROW(buildFromArray(result, array, 5), |
| dbcommon::TransactionAbortException); |
| } |
| |
| Int128 singleDivide(uint32_t* dividend, int64_t dividendLength, |
| uint32_t divisor, Int128& remainder, |
| bool dividendWasNegative, bool divisorWasNegative); |
| |
| TEST(Int128, testSingleDivide) { |
| Int128 remainder; |
| uint32_t dividend[4]; |
| |
| dividend[0] = 23; |
| Int128 result = singleDivide(dividend, 1, 5, remainder, true, false); |
| EXPECT_EQ(-4, result.toLong()); |
| EXPECT_EQ(-3, remainder.toLong()); |
| |
| dividend[0] = 0x100; |
| dividend[1] = 0x120; |
| dividend[2] = 0x140; |
| dividend[3] = 0x160; |
| result = singleDivide(dividend, 4, 0x20, remainder, false, false); |
| EXPECT_EQ("0x00000008000000090000000a0000000b", result.toHexString()); |
| EXPECT_EQ(0, remainder.toLong()); |
| |
| dividend[0] = 0x101; |
| dividend[1] = 0x122; |
| dividend[2] = 0x143; |
| dividend[3] = 0x164; |
| result = singleDivide(dividend, 4, 0x20, remainder, false, false); |
| EXPECT_EQ("0x00000008080000091000000a1800000b", result.toHexString()); |
| EXPECT_EQ(4, remainder.toLong()); |
| |
| dividend[0] = 0x12345678; |
| dividend[1] = 0x9abcdeff; |
| dividend[2] = 0xfedcba09; |
| dividend[3] = 0x87654321; |
| result = singleDivide(dividend, 4, 123, remainder, false, false); |
| EXPECT_EQ("0x0025e390971c97aaaaa84c7077bc23ed", result.toHexString()); |
| EXPECT_EQ(0x42, remainder.toLong()); |
| } |
| |
| TEST(Int128, testDivide) { |
| Int128 dividend; |
| Int128 result; |
| Int128 remainder; |
| |
| dividend = 0x12345678; |
| result = dividend.divide(0x123456789abcdef0, remainder); |
| EXPECT_EQ(0, result.toLong()); |
| EXPECT_EQ(0x12345678, remainder.toLong()); |
| |
| EXPECT_THROW(dividend.divide(0, remainder), std::runtime_error); |
| |
| dividend = Int128(0x123456789abcdeff, 0xfedcba0987654321); |
| result = dividend.divide(123, remainder); |
| EXPECT_EQ("0x0025e390971c97aaaaa84c7077bc23ed", result.toHexString()); |
| EXPECT_EQ(0x42, remainder.toLong()); |
| |
| dividend = Int128(0x111111112fffffff, 0xeeeeeeeedddddddd); |
| result = dividend.divide(0x1111111123456789, remainder); |
| EXPECT_EQ("0x000000000000000100000000beeeeef7", result.toHexString()); |
| EXPECT_EQ("0x0000000000000000037d3b3d60479aae", remainder.toHexString()); |
| |
| dividend = 1234234662345; |
| result = dividend.divide(642337, remainder); |
| EXPECT_EQ(1921475, result.toLong()); |
| EXPECT_EQ(175270, remainder.toLong()); |
| |
| dividend = Int128(0x42395ADC0534AB4C, 0x59D109ADF9892FCA); |
| result = dividend.divide(0x1234F09DC19A, remainder); |
| EXPECT_EQ("0x000000000003a327c1348bccd2f06c27", result.toHexString()); |
| EXPECT_EQ("0x000000000000000000000cacef73b954", remainder.toHexString()); |
| |
| dividend = Int128(0xfffffffffffffff, 0xf000000000000000); |
| result = dividend.divide(Int128(0, 0x1000000000000000), remainder); |
| EXPECT_EQ("0x0000000000000000ffffffffffffffff", result.toHexString()); |
| EXPECT_EQ(0, remainder.toLong()); |
| |
| dividend = Int128(0x4000000000000000, 0); |
| result = dividend.divide(Int128(0, 0x400000007fffffff), remainder); |
| EXPECT_EQ("0x0000000000000000fffffffe00000007", result.toHexString()); |
| EXPECT_EQ("0x00000000000000003ffffffa80000007", remainder.toHexString()); |
| } |
| |
| TEST(Int128, testToString) { |
| Int128 num = Int128(0x123456789abcdef0, 0xfedcba0987654321); |
| EXPECT_EQ("24197857203266734881846307133640229665", num.toString()); |
| |
| num = Int128(0, 0xab54a98ceb1f0ad2); |
| EXPECT_EQ("12345678901234567890", num.toString()); |
| |
| num = 12345678; |
| EXPECT_EQ("12345678", num.toString()); |
| |
| num = -1234; |
| EXPECT_EQ("-1234", num.toString()); |
| |
| num = Int128(0x13f20d9c2, 0xfff89d38e1c70cb1); |
| EXPECT_EQ("98765432109876543210987654321", num.toString()); |
| num.negate(); |
| EXPECT_EQ("-98765432109876543210987654321", num.toString()); |
| |
| num = Int128("10000000000000000000000000000000000000"); |
| EXPECT_EQ("10000000000000000000000000000000000000", num.toString()); |
| |
| num = Int128("-1234"); |
| EXPECT_EQ("-1234", num.toString()); |
| |
| num = Int128("-12345678901122334455667788990011122233"); |
| EXPECT_EQ("-12345678901122334455667788990011122233", num.toString()); |
| } |
| |
| TEST(Int128, testToDecimalString) { |
| Int128 num = Int128("98765432109876543210987654321098765432"); |
| EXPECT_EQ("98765432109876543210987654321098765432", num.toDecimalString(0)); |
| EXPECT_EQ("987654321098765432109876543210987.65432", num.toDecimalString(5)); |
| num.negate(); |
| EXPECT_EQ("-98765432109876543210987654321098765432", num.toDecimalString(0)); |
| EXPECT_EQ("-987654321098765432109876543210987.65432", num.toDecimalString(5)); |
| num = 123; |
| EXPECT_EQ("12.3", num.toDecimalString(1)); |
| EXPECT_EQ("0.123", num.toDecimalString(3)); |
| EXPECT_EQ("0.0123", num.toDecimalString(4)); |
| EXPECT_EQ("0.00123", num.toDecimalString(5)); |
| |
| num = -123; |
| EXPECT_EQ("-123", num.toDecimalString(0)); |
| EXPECT_EQ("-12.3", num.toDecimalString(1)); |
| EXPECT_EQ("-0.123", num.toDecimalString(3)); |
| EXPECT_EQ("-0.0123", num.toDecimalString(4)); |
| EXPECT_EQ("-0.00123", num.toDecimalString(5)); |
| } |
| |
| TEST(Int128, testInt128Scale) { |
| Int128 num = Int128(10); |
| bool overflow = false; |
| |
| num = scaleUpInt128ByPowerOfTen(num, 0, overflow); |
| EXPECT_FALSE(overflow); |
| EXPECT_EQ(Int128(10), num); |
| |
| num = scaleUpInt128ByPowerOfTen(num, 5, overflow); |
| EXPECT_FALSE(overflow); |
| EXPECT_EQ(Int128(1000000), num); |
| |
| num = scaleUpInt128ByPowerOfTen(num, 5, overflow); |
| EXPECT_FALSE(overflow); |
| EXPECT_EQ(Int128(100000000000l), num); |
| |
| num = scaleUpInt128ByPowerOfTen(num, 20, overflow); |
| EXPECT_FALSE(overflow); |
| EXPECT_EQ(Int128("10000000000000000000000000000000"), num); |
| |
| scaleUpInt128ByPowerOfTen(num, 10, overflow); |
| EXPECT_TRUE(overflow); |
| |
| scaleUpInt128ByPowerOfTen(Int128::maximumValue(), 0, overflow); |
| EXPECT_FALSE(overflow); |
| |
| scaleUpInt128ByPowerOfTen(Int128::maximumValue(), 1, overflow); |
| EXPECT_TRUE(overflow); |
| |
| num = scaleDownInt128ByPowerOfTen(Int128(10001), 0); |
| EXPECT_EQ(Int128(10001), num); |
| |
| num = scaleDownInt128ByPowerOfTen(Int128(10001), 2); |
| EXPECT_EQ(Int128(100), num); |
| |
| num = scaleDownInt128ByPowerOfTen(Int128(10000), 5); |
| EXPECT_EQ(Int128(0), num); |
| } |
| |
| } // namespace orc |