[98496] | 1 | /* $Id: tstRTNoCrt-5.cpp 98512 2023-02-08 21:32:53Z vboxsync $ */
|
---|
| 2 | /** @file
|
---|
| 3 | * IPRT Testcase - Testcase for the No-CRT 64-bit integer support.
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
| 7 | * Copyright (C) 2023 Oracle and/or its affiliates.
|
---|
| 8 | *
|
---|
| 9 | * This file is part of VirtualBox base platform packages, as
|
---|
| 10 | * available from https://www.virtualbox.org.
|
---|
| 11 | *
|
---|
| 12 | * This program is free software; you can redistribute it and/or
|
---|
| 13 | * modify it under the terms of the GNU General Public License
|
---|
| 14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
| 15 | * License.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful, but
|
---|
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 20 | * General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
| 24 | *
|
---|
| 25 | * The contents of this file may alternatively be used under the terms
|
---|
| 26 | * of the Common Development and Distribution License Version 1.0
|
---|
| 27 | * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
|
---|
| 28 | * in the VirtualBox distribution, in which case the provisions of the
|
---|
| 29 | * CDDL are applicable instead of those of the GPL.
|
---|
| 30 | *
|
---|
| 31 | * You may elect to license modified versions of this file under the
|
---|
| 32 | * terms and conditions of either the GPL or the CDDL or both.
|
---|
| 33 | *
|
---|
| 34 | * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
|
---|
| 35 | */
|
---|
| 36 |
|
---|
| 37 |
|
---|
| 38 | /*********************************************************************************************************************************
|
---|
| 39 | * Header Files *
|
---|
| 40 | *********************************************************************************************************************************/
|
---|
| 41 | #include <iprt/uint64.h>
|
---|
| 42 | #include <iprt/test.h>
|
---|
| 43 | #include <iprt/string.h>
|
---|
| 44 | #include <iprt/rand.h>
|
---|
| 45 |
|
---|
| 46 |
|
---|
| 47 | /*********************************************************************************************************************************
|
---|
| 48 | * Defined Constants And Macros *
|
---|
| 49 | *********************************************************************************************************************************/
|
---|
[98510] | 50 | #ifdef DEBUG
|
---|
| 51 | # define RANDOM_LOOPS _256K
|
---|
| 52 | #else
|
---|
| 53 | # define RANDOM_LOOPS _1M
|
---|
| 54 | #endif
|
---|
[98496] | 55 |
|
---|
| 56 |
|
---|
| 57 | /*********************************************************************************************************************************
|
---|
| 58 | * Structures and Typedefs *
|
---|
| 59 | *********************************************************************************************************************************/
|
---|
| 60 | typedef struct TSTRTNOCRT5SHIFT
|
---|
| 61 | {
|
---|
| 62 | uint64_t uValue;
|
---|
| 63 | uint8_t cShift;
|
---|
| 64 | uint64_t uExpected;
|
---|
| 65 | } TSTRTNOCRT5SHIFT;
|
---|
| 66 |
|
---|
| 67 | typedef struct TSTRTNOCRT5MULT
|
---|
| 68 | {
|
---|
| 69 | uint64_t uFactor1, uFactor2;
|
---|
| 70 | uint64_t uExpected;
|
---|
| 71 | } TSTRTNOCRT5MULT;
|
---|
| 72 |
|
---|
| 73 | typedef struct TSTRTNOCRT5DIV
|
---|
| 74 | {
|
---|
| 75 | uint64_t uDividend, uDivisor;
|
---|
[98510] | 76 | uint64_t uQuotient, uRemainder;
|
---|
[98496] | 77 | } TSTRTNOCRT5DIV;
|
---|
| 78 |
|
---|
| 79 |
|
---|
| 80 | /*********************************************************************************************************************************
|
---|
| 81 | * Global Variables *
|
---|
| 82 | *********************************************************************************************************************************/
|
---|
| 83 | RTTEST g_hTest;
|
---|
| 84 |
|
---|
| 85 | TSTRTNOCRT5SHIFT volatile const g_aShiftRight[] =
|
---|
| 86 | {
|
---|
| 87 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 0, UINT64_C(0x8e7e6e5e4e3e2e1e) },
|
---|
| 88 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 8, UINT64_C(0x008e7e6e5e4e3e2e) },
|
---|
| 89 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 16, UINT64_C(0x00008e7e6e5e4e3e) },
|
---|
| 90 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 24, UINT64_C(0x0000008e7e6e5e4e) },
|
---|
| 91 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 28, UINT64_C(0x00000008e7e6e5e4) },
|
---|
| 92 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 32, UINT64_C(0x000000008e7e6e5e) },
|
---|
| 93 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 36, UINT64_C(0x0000000008e7e6e5) },
|
---|
| 94 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 40, UINT64_C(0x00000000008e7e6e) },
|
---|
| 95 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 44, UINT64_C(0x000000000008e7e6) },
|
---|
| 96 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 48, UINT64_C(0x0000000000008e7e) },
|
---|
| 97 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 52, UINT64_C(0x00000000000008e7) },
|
---|
| 98 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 56, UINT64_C(0x000000000000008e) },
|
---|
| 99 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 60, UINT64_C(0x0000000000000008) },
|
---|
| 100 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 64, UINT64_C(0x0000000000000000) },
|
---|
| 101 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 65, UINT64_C(0x0000000000000000) },
|
---|
| 102 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 99, UINT64_C(0x0000000000000000) },
|
---|
| 103 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 127, UINT64_C(0x0000000000000000) },
|
---|
| 104 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 132, UINT64_C(0x0000000000000000) },
|
---|
| 105 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 255, UINT64_C(0x0000000000000000) },
|
---|
| 106 | };
|
---|
| 107 |
|
---|
| 108 |
|
---|
| 109 | static void tstShiftRight()
|
---|
| 110 | {
|
---|
| 111 | RTTestSub(g_hTest, "64-bit unsigned shift right");
|
---|
| 112 |
|
---|
| 113 | /* static tests from array. */
|
---|
| 114 | for (size_t i = 0; i < RT_ELEMENTS(g_aShiftRight); i++)
|
---|
| 115 | {
|
---|
| 116 | uint64_t const uResult = g_aShiftRight[i].uValue >> g_aShiftRight[i].cShift;
|
---|
| 117 | if (uResult != g_aShiftRight[i].uExpected)
|
---|
| 118 | RTTestFailed(g_hTest, "i=%u uValue=%#018RX64 SHR %u => %#018RX64, expected %#018RX64",
|
---|
| 119 | i, g_aShiftRight[i].uValue, g_aShiftRight[i].cShift, uResult, g_aShiftRight[i].uExpected);
|
---|
| 120 | }
|
---|
| 121 |
|
---|
| 122 | /* Random values via uint64. */
|
---|
| 123 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 124 | {
|
---|
| 125 | uint64_t const uValue = RTRandU64();
|
---|
| 126 | uint8_t const cShift = (uint8_t)RTRandU32Ex(0, i & 3 ? 63 : 255);
|
---|
| 127 | uint64_t const uResult = uValue >> cShift;
|
---|
| 128 | RTUINT64U uExpected = { uValue };
|
---|
| 129 | if (cShift <= 63)
|
---|
| 130 | RTUInt64AssignShiftRight(&uExpected, cShift);
|
---|
| 131 | else
|
---|
| 132 | uExpected.u = 0;
|
---|
| 133 | if (uResult != uExpected.u)
|
---|
| 134 | RTTestFailed(g_hTest, "uValue=%#018RX64 SHR %u => %#018RX64, expected %#018RX64", uValue, cShift, uResult, uExpected.u);
|
---|
| 135 | }
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 |
|
---|
| 139 | TSTRTNOCRT5SHIFT volatile const g_aShiftSignedRight[] =
|
---|
| 140 | {
|
---|
| 141 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 0, UINT64_C(0x8e7e6e5e4e3e2e1e) },
|
---|
| 142 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 8, UINT64_C(0xff8e7e6e5e4e3e2e) },
|
---|
| 143 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 16, UINT64_C(0xffff8e7e6e5e4e3e) },
|
---|
| 144 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 24, UINT64_C(0xffffff8e7e6e5e4e) },
|
---|
| 145 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 28, UINT64_C(0xfffffff8e7e6e5e4) },
|
---|
| 146 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 32, UINT64_C(0xffffffff8e7e6e5e) },
|
---|
| 147 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 36, UINT64_C(0xfffffffff8e7e6e5) },
|
---|
| 148 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 40, UINT64_C(0xffffffffff8e7e6e) },
|
---|
| 149 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 44, UINT64_C(0xfffffffffff8e7e6) },
|
---|
| 150 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 48, UINT64_C(0xffffffffffff8e7e) },
|
---|
| 151 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 52, UINT64_C(0xfffffffffffff8e7) },
|
---|
| 152 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 56, UINT64_C(0xffffffffffffff8e) },
|
---|
| 153 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 60, UINT64_C(0xfffffffffffffff8) },
|
---|
| 154 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 64, UINT64_C(0xffffffffffffffff) },
|
---|
| 155 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 65, UINT64_C(0xffffffffffffffff) },
|
---|
| 156 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 99, UINT64_C(0xffffffffffffffff) },
|
---|
| 157 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 127, UINT64_C(0xffffffffffffffff) },
|
---|
| 158 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 132, UINT64_C(0xffffffffffffffff) },
|
---|
| 159 | { UINT64_C(0x8e7e6e5e4e3e2e1e), 255, UINT64_C(0xffffffffffffffff) },
|
---|
| 160 |
|
---|
| 161 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 0, UINT64_C(0x7e8e6e5e4e3e2e1e) },
|
---|
| 162 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 8, UINT64_C(0x007e8e6e5e4e3e2e) },
|
---|
| 163 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 16, UINT64_C(0x00007e8e6e5e4e3e) },
|
---|
| 164 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 24, UINT64_C(0x0000007e8e6e5e4e) },
|
---|
| 165 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 28, UINT64_C(0x00000007e8e6e5e4) },
|
---|
| 166 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 32, UINT64_C(0x000000007e8e6e5e) },
|
---|
| 167 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 36, UINT64_C(0x0000000007e8e6e5) },
|
---|
| 168 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 40, UINT64_C(0x00000000007e8e6e) },
|
---|
| 169 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 44, UINT64_C(0x000000000007e8e6) },
|
---|
| 170 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 48, UINT64_C(0x0000000000007e8e) },
|
---|
| 171 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 52, UINT64_C(0x00000000000007e8) },
|
---|
| 172 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 56, UINT64_C(0x000000000000007e) },
|
---|
| 173 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 60, UINT64_C(0x0000000000000007) },
|
---|
| 174 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 64, UINT64_C(0x0000000000000000) },
|
---|
| 175 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 65, UINT64_C(0x0000000000000000) },
|
---|
| 176 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 99, UINT64_C(0x0000000000000000) },
|
---|
| 177 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 127, UINT64_C(0x0000000000000000) },
|
---|
| 178 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 132, UINT64_C(0x0000000000000000) },
|
---|
| 179 | { UINT64_C(0x7e8e6e5e4e3e2e1e), 255, UINT64_C(0x0000000000000000) },
|
---|
| 180 | };
|
---|
| 181 |
|
---|
| 182 | static void tstShiftRightArithmetic()
|
---|
| 183 | {
|
---|
| 184 | RTTestSub(g_hTest, "64-bit signed shift right");
|
---|
| 185 |
|
---|
| 186 | /* static tests from array. */
|
---|
| 187 | for (size_t i = 0; i < RT_ELEMENTS(g_aShiftSignedRight); i++)
|
---|
| 188 | {
|
---|
| 189 | int64_t const iResult = (int64_t)g_aShiftSignedRight[i].uValue >> g_aShiftSignedRight[i].cShift;
|
---|
| 190 | if ((uint64_t)iResult != g_aShiftSignedRight[i].uExpected)
|
---|
| 191 | RTTestFailed(g_hTest, "i=%u iValue=%#018RX64 SAR %u => %#018RX64, expected %#018RX64", i, g_aShiftSignedRight[i].uValue,
|
---|
| 192 | g_aShiftSignedRight[i].cShift, iResult, g_aShiftSignedRight[i].uExpected);
|
---|
| 193 | }
|
---|
| 194 |
|
---|
| 195 | /* Random values via uint64. */
|
---|
| 196 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 197 | {
|
---|
| 198 | uint64_t const uValue = RTRandU64();
|
---|
| 199 | uint8_t const cShift = (uint8_t)RTRandU32Ex(0, i & 3 ? 63 : 255);
|
---|
| 200 | int64_t const iResult = (int64_t)uValue >> cShift;
|
---|
| 201 | RTUINT64U uExpected = { uValue };
|
---|
| 202 | if (cShift > 63)
|
---|
| 203 | uExpected.u = RT_BIT_64(63) & uValue ? UINT64_MAX : 0;
|
---|
| 204 | else
|
---|
| 205 | {
|
---|
| 206 | RTUInt64AssignShiftRight(&uExpected, cShift);
|
---|
| 207 | if (RT_BIT_64(63) & uValue)
|
---|
| 208 | uExpected.u |= UINT64_MAX << (63 - cShift);
|
---|
| 209 | }
|
---|
| 210 | if ((uint64_t)iResult != uExpected.u)
|
---|
| 211 | RTTestFailed(g_hTest, "uValue=%#018RX64 SHR %u => %#018RX64, expected %#018RX64", uValue, cShift, iResult, uExpected.u);
|
---|
| 212 | }
|
---|
| 213 | }
|
---|
| 214 |
|
---|
| 215 | TSTRTNOCRT5SHIFT volatile const g_aShiftLeft[] =
|
---|
| 216 | {
|
---|
| 217 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 0, UINT64_C(0x8e7d6c5e4a3e2b1e) },
|
---|
| 218 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 8, UINT64_C(0x7d6c5e4a3e2b1e00) },
|
---|
| 219 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 16, UINT64_C(0x6c5e4a3e2b1e0000) },
|
---|
| 220 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 24, UINT64_C(0x5e4a3e2b1e000000) },
|
---|
| 221 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 28, UINT64_C(0xe4a3e2b1e0000000) },
|
---|
| 222 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 32, UINT64_C(0x4a3e2b1e00000000) },
|
---|
| 223 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 36, UINT64_C(0xa3e2b1e000000000) },
|
---|
| 224 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 40, UINT64_C(0x3e2b1e0000000000) },
|
---|
| 225 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 44, UINT64_C(0xe2b1e00000000000) },
|
---|
| 226 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 48, UINT64_C(0x2b1e000000000000) },
|
---|
| 227 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 52, UINT64_C(0xb1e0000000000000) },
|
---|
| 228 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 56, UINT64_C(0x1e00000000000000) },
|
---|
| 229 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 60, UINT64_C(0xe000000000000000) },
|
---|
| 230 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 64, UINT64_C(0x0000000000000000) },
|
---|
| 231 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 65, UINT64_C(0x0000000000000000) },
|
---|
| 232 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 99, UINT64_C(0x0000000000000000) },
|
---|
| 233 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 127, UINT64_C(0x0000000000000000) },
|
---|
| 234 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 132, UINT64_C(0x0000000000000000) },
|
---|
| 235 | { UINT64_C(0x8e7d6c5e4a3e2b1e), 255, UINT64_C(0x0000000000000000) },
|
---|
| 236 | };
|
---|
| 237 |
|
---|
| 238 | static void tstShiftLeft()
|
---|
| 239 | {
|
---|
| 240 | RTTestSub(g_hTest, "64-bit shift left");
|
---|
| 241 |
|
---|
| 242 | /* static tests from array. */
|
---|
| 243 | for (size_t i = 0; i < RT_ELEMENTS(g_aShiftLeft); i++)
|
---|
| 244 | {
|
---|
| 245 | uint64_t const uResult = g_aShiftLeft[i].uValue << g_aShiftLeft[i].cShift;
|
---|
| 246 | if (uResult != g_aShiftLeft[i].uExpected)
|
---|
| 247 | RTTestFailed(g_hTest, "i=%u iValue=%#018RX64 SHL %u => %#018RX64, expected %#018RX64", i, g_aShiftLeft[i].uValue,
|
---|
| 248 | g_aShiftLeft[i].cShift, uResult, g_aShiftLeft[i].uExpected);
|
---|
| 249 | }
|
---|
| 250 |
|
---|
| 251 | for (size_t i = 0; i < RT_ELEMENTS(g_aShiftLeft); i++)
|
---|
| 252 | {
|
---|
| 253 | int64_t const iResult = (int64_t)g_aShiftLeft[i].uValue << g_aShiftLeft[i].cShift;
|
---|
| 254 | if ((uint64_t)iResult != g_aShiftLeft[i].uExpected)
|
---|
| 255 | RTTestFailed(g_hTest, "i=%u iValue=%#018RX64 SHL %u => %#018RX64, expected %#018RX64 [signed]", i, g_aShiftLeft[i].uValue,
|
---|
| 256 | g_aShiftLeft[i].cShift, iResult, g_aShiftLeft[i].uExpected);
|
---|
| 257 | }
|
---|
| 258 |
|
---|
| 259 | /* Random values via uint64. */
|
---|
| 260 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 261 | {
|
---|
| 262 | uint64_t const uValue = RTRandU64();
|
---|
| 263 | uint8_t const cShift = (uint8_t)RTRandU32Ex(0, i & 3 ? 63 : 255);
|
---|
| 264 | uint64_t const uResult = uValue << cShift;
|
---|
| 265 | RTUINT64U uExpected = { uValue };
|
---|
| 266 | if (cShift > 63)
|
---|
| 267 | uExpected.u = 0;
|
---|
| 268 | else
|
---|
| 269 | RTUInt64AssignShiftLeft(&uExpected, cShift);
|
---|
| 270 |
|
---|
| 271 | if (uResult != uExpected.u)
|
---|
| 272 | RTTestFailed(g_hTest, "uValue=%#018RX64 SHR %u => %#018RX64, expected %#018RX64", uValue, cShift, uResult, uExpected.u);
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 276 | {
|
---|
| 277 | uint64_t const uValue = RTRandU64();
|
---|
| 278 | uint8_t const cShift = (uint8_t)RTRandU32Ex(0, i & 3 ? 63 : 255);
|
---|
| 279 | int64_t const iResult = (int64_t)uValue << cShift;
|
---|
| 280 | RTUINT64U uExpected = { uValue };
|
---|
| 281 | if (cShift > 63)
|
---|
| 282 | uExpected.u = 0;
|
---|
| 283 | else
|
---|
| 284 | RTUInt64AssignShiftLeft(&uExpected, cShift);
|
---|
| 285 |
|
---|
| 286 | if ((uint64_t)iResult != uExpected.u)
|
---|
| 287 | RTTestFailed(g_hTest, "uValue=%#018RX64 SHR %u => %#018RX64, expected %#018RX64", uValue, cShift, iResult, uExpected.u);
|
---|
| 288 | }
|
---|
| 289 | }
|
---|
| 290 |
|
---|
| 291 |
|
---|
| 292 | TSTRTNOCRT5MULT volatile const g_aMult[] =
|
---|
| 293 | {
|
---|
| 294 | { UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000), /* => */ UINT64_C(0x0000000000000000) },
|
---|
| 295 | { UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000001), /* => */ UINT64_C(0x0000000000000001) },
|
---|
| 296 | { UINT64_C(0x000000001203879f), UINT64_C(0x0000000094585638), /* => */ UINT64_C(0x0A7041AFAAFD14C8) },
|
---|
| 297 | { UINT64_C(0x0000000100000000), UINT64_C(0x0000000010329484), /* => */ UINT64_C(0x1032948400000000) },
|
---|
| 298 | { UINT64_C(0x0958609457ad0f03), UINT64_C(0x8f9d0a07d9f83145), /* => */ UINT64_C(0xC77D9538D76C9ECF) },
|
---|
| 299 | };
|
---|
| 300 |
|
---|
| 301 | static void tstMultiplication()
|
---|
| 302 | {
|
---|
| 303 | RTTestSub(g_hTest, "64-bit multiplication");
|
---|
| 304 |
|
---|
| 305 | /* static tests from array. */
|
---|
| 306 | for (size_t i = 0; i < RT_ELEMENTS(g_aMult); i++)
|
---|
| 307 | {
|
---|
| 308 | uint64_t const uResult = g_aMult[i].uFactor1 * g_aMult[i].uFactor2;
|
---|
| 309 | if (uResult != g_aMult[i].uExpected)
|
---|
| 310 | RTTestFailed(g_hTest, "i=%u %#018RX64 * %#018RX64 => %#018RX64, expected %#018RX64",
|
---|
| 311 | i, g_aMult[i].uFactor1, g_aMult[i].uFactor2, uResult, g_aMult[i].uExpected);
|
---|
| 312 | }
|
---|
| 313 | for (size_t i = 0; i < RT_ELEMENTS(g_aMult); i++)
|
---|
| 314 | {
|
---|
| 315 | uint64_t const uResult = g_aMult[i].uFactor2 * g_aMult[i].uFactor1;
|
---|
| 316 | if (uResult != g_aMult[i].uExpected)
|
---|
| 317 | RTTestFailed(g_hTest, "i=%u %#018RX64 * %#018RX64 => %#018RX64, expected %#018RX64 (f2*f1)",
|
---|
| 318 | i, g_aMult[i].uFactor2, g_aMult[i].uFactor1, uResult, g_aMult[i].uExpected);
|
---|
| 319 | }
|
---|
| 320 | for (size_t i = 0; i < RT_ELEMENTS(g_aMult); i++)
|
---|
| 321 | {
|
---|
| 322 | int64_t const iResult = (int64_t)g_aMult[i].uFactor1 * (int64_t)g_aMult[i].uFactor2;
|
---|
| 323 | if ((uint64_t)iResult != g_aMult[i].uExpected)
|
---|
| 324 | RTTestFailed(g_hTest, "i=%u %#018RX64 * %#018RX64 => %#018RX64, expected %#018RX64 (signed)",
|
---|
| 325 | i, g_aMult[i].uFactor1, g_aMult[i].uFactor2, iResult, g_aMult[i].uExpected);
|
---|
| 326 | }
|
---|
| 327 |
|
---|
| 328 | /* Random values via uint64. */
|
---|
| 329 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 330 | {
|
---|
| 331 | RTUINT64U const uFactor1 = { RTRandU64Ex(0, i & 7 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 332 | RTUINT64U const uFactor2 = { RTRandU64Ex(0, i & 3 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 333 | uint64_t const uResult = uFactor1.u * uFactor2.u;
|
---|
| 334 | RTUINT64U uExpected;
|
---|
| 335 | RTUInt64Mul(&uExpected, &uFactor1, &uFactor2);
|
---|
| 336 |
|
---|
| 337 | if (uResult != uExpected.u)
|
---|
| 338 | RTTestFailed(g_hTest, "%#018RX64 * %#018RX64 => %#018RX64, expected %#018RX64", uFactor1.u, uFactor2.u, uResult, uExpected.u);
|
---|
| 339 | }
|
---|
| 340 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 341 | {
|
---|
| 342 | RTUINT64U const uFactor1 = { RTRandU64Ex(0, i & 7 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 343 | RTUINT64U const uFactor2 = { RTRandU64Ex(0, i & 3 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 344 | int64_t const iResult = (int64_t)uFactor1.u * (int64_t)uFactor2.u;
|
---|
| 345 | RTUINT64U uExpected;
|
---|
| 346 | RTUInt64Mul(&uExpected, &uFactor1, &uFactor2);
|
---|
| 347 |
|
---|
| 348 | if ((uint64_t)iResult != uExpected.u)
|
---|
| 349 | RTTestFailed(g_hTest, "%#018RX64 * %#018RX64 => %#018RX64, expected %#018RX64 (signed)",
|
---|
| 350 | uFactor1.u, uFactor2.u, iResult, uExpected.u);
|
---|
| 351 | }
|
---|
| 352 | }
|
---|
| 353 |
|
---|
| 354 |
|
---|
| 355 | TSTRTNOCRT5DIV volatile const g_aDivU[] =
|
---|
| 356 | {
|
---|
| 357 | { UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000001), /* => */ UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000) },
|
---|
| 358 | { UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000001), /* => */ UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000000) },
|
---|
| 359 | { UINT64_C(0x0000000000000002), UINT64_C(0x0000000000000002), /* => */ UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000000) },
|
---|
| 360 | { UINT64_C(0x0000000000000003), UINT64_C(0x0000000000000002), /* => */ UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000001) },
|
---|
| 361 | { UINT64_C(0x0000000009821348), UINT64_C(0x0000000023949583), /* => */ UINT64_C(0x0000000000000000), UINT64_C(0x0000000009821348) },
|
---|
| 362 | { UINT64_C(0x0000000079821348), UINT64_C(0x0000000023949583), /* => */ UINT64_C(0x0000000000000003), UINT64_C(0x000000000EC452BF) },
|
---|
| 363 | { UINT64_C(0x0439583044583049), UINT64_C(0x0984987539485732), /* => */ UINT64_C(0x0000000000000000), UINT64_C(0x0439583044583049) },
|
---|
| 364 | { UINT64_C(0xf439583044583049), UINT64_C(0x0984987539485732), /* => */ UINT64_C(0x0000000000000019), UINT64_C(0x064674BDAC47AC67) },
|
---|
| 365 | { UINT64_C(0xdf8305930df94306), UINT64_C(0x00000043d9dfa039), /* => */ UINT64_C(0x00000000034B4D9D), UINT64_C(0x0000000990EFDB11) },
|
---|
| 366 | { UINT64_C(0xff9f939d0f0302d9), UINT64_C(0x0000000000000042), /* => */ UINT64_C(0x03DF823C8FBE1B31), UINT64_C(0x0000000000000037) },
|
---|
[98510] | 367 | { UINT64_C(0xffffffffffffffff), UINT64_C(0x0000000000000042), /* => */ UINT64_C(0x03E0F83E0F83E0F8), UINT64_C(0x000000000000000f) },
|
---|
| 368 | { UINT64_C(0xffffffffffffffff), UINT64_C(0x0000000000000007), /* => */ UINT64_C(0x2492492492492492), UINT64_C(0x0000000000000001) },
|
---|
| 369 | { UINT64_C(0xe1f17ac834b412b4), UINT64_C(0xda38027453291b1e), /* => */ UINT64_C(0x0000000000000001), UINT64_C(0x07b97853e18af796) },
|
---|
| 370 | /* These should trigger the rare overflow condition in the 32-bit approximation algorithm. */
|
---|
| 371 | { UINT64_C(0xe101721f65eb6226), UINT64_C(0x0000028180a483fa), /* => */ UINT64_C(0x000000000059CA9C), UINT64_C(0x000002814F9DB1CE) },
|
---|
| 372 | { UINT64_C(0x8b0a3ed1cda21100), UINT64_C(0x8b0a3ed1cda231d4), /* => */ UINT64_C(0x0000000000000000), UINT64_C(0x8B0A3ED1CDA21100) },
|
---|
| 373 | { UINT64_C(0xf1387d27f3a0c583), UINT64_C(0x000735f0d9661f93), /* => */ UINT64_C(0x0000000000002173), UINT64_C(0x000735F020AEA37A) },
|
---|
| 374 | { UINT64_C(0xb690b755d6f4496f), UINT64_C(0x000143027675d0d7), /* => */ UINT64_C(0x00000000000090b0), UINT64_C(0x00014302207bc59f) },
|
---|
| 375 | { UINT64_C(0x78a5b3efc6c82cf7), UINT64_C(0x00000f9b4400a9f0), /* => */ UINT64_C(0x000000000007bb06), UINT64_C(0x00000f9b0d11e157) },
|
---|
| 376 | { UINT64_C(0x8ae75b071b094efc), UINT64_C(0x0020904259dedd1e), /* => */ UINT64_C(0x0000000000000443), UINT64_C(0x002090421a40f822) },
|
---|
| 377 | { UINT64_C(0x90c9fb203c85fa7c), UINT64_C(0x000001ef807ef1e9), /* => */ UINT64_C(0x00000000004ace0e), UINT64_C(0x000001ef219141be) },
|
---|
| 378 | { UINT64_C(0xf9ae8ea6b31751df), UINT64_C(0x00004281110e2327), /* => */ UINT64_C(0x000000000003c11e), UINT64_C(0x00004280a179cc4d) },
|
---|
| 379 | /* These trigger an even more special case, where the QapproxDividend calculation overflows. */
|
---|
| 380 | { UINT64_C(0xffffffffffffffff), UINT64_C(0x00003C11D54B525f), /* => */ UINT64_C(0x00000000000442FF), UINT64_C(0x00003C11D540755E) },
|
---|
| 381 | { UINT64_C(0xfffffffffefa1235), UINT64_C(0x0001001702112f8c), /* => */ UINT64_C(0x000000000000FFE8), UINT64_C(0x00010017010A8755) },
|
---|
[98496] | 382 | };
|
---|
| 383 |
|
---|
| 384 | static void tstUnsignedDivision()
|
---|
| 385 | {
|
---|
| 386 | RTTestSub(g_hTest, "64-bit unsigned division");
|
---|
| 387 |
|
---|
[98512] | 388 | /*
|
---|
[98496] | 389 | * static tests from array.
|
---|
| 390 | */
|
---|
| 391 | for (size_t i = 0; i < RT_ELEMENTS(g_aDivU); i++)
|
---|
| 392 | {
|
---|
| 393 | uint64_t const uResult = g_aDivU[i].uDividend / g_aDivU[i].uDivisor; /* aulldiv */
|
---|
| 394 | if (uResult != g_aDivU[i].uQuotient)
|
---|
| 395 | RTTestFailed(g_hTest, "i=%u %#018RX64 / %#018RX64 => %#018RX64, expected %#018RX64",
|
---|
| 396 | i, g_aDivU[i].uDividend, g_aDivU[i].uDivisor, uResult, g_aDivU[i].uQuotient);
|
---|
| 397 | }
|
---|
| 398 | for (size_t i = 0; i < RT_ELEMENTS(g_aDivU); i++)
|
---|
| 399 | {
|
---|
| 400 | uint64_t const uResult = g_aDivU[i].uDividend % g_aDivU[i].uDivisor; /* aullrem */
|
---|
[98510] | 401 | if (uResult != g_aDivU[i].uRemainder)
|
---|
[98496] | 402 | RTTestFailed(g_hTest, "i=%u %#018RX64 %% %#018RX64 => %#018RX64, expected %#018RX64",
|
---|
[98510] | 403 | i, g_aDivU[i].uDividend, g_aDivU[i].uDivisor, uResult, g_aDivU[i].uRemainder);
|
---|
[98496] | 404 | }
|
---|
| 405 | for (size_t i = 0; i < RT_ELEMENTS(g_aDivU); i++)
|
---|
| 406 | {
|
---|
[98510] | 407 | uint64_t const uDividend = g_aDivU[i].uDividend;
|
---|
| 408 | uint64_t const uDivisor = g_aDivU[i].uDivisor;
|
---|
| 409 | uint64_t const uQuotient = uDividend / uDivisor; /* auldvrm hopefully - only not in unoptimized builds. */
|
---|
| 410 | uint64_t const uRemainder = uDividend % uDivisor;
|
---|
| 411 | if ( uQuotient != g_aDivU[i].uQuotient
|
---|
| 412 | || uRemainder != g_aDivU[i].uRemainder)
|
---|
[98496] | 413 | RTTestFailed(g_hTest, "i=%u %#018RX64 / %#018RX64 => q=%#018RX64 r=%#018RX64, expected q=%#018RX64 r=%#018RX64",
|
---|
| 414 | i, g_aDivU[i].uDividend, g_aDivU[i].uDivisor,
|
---|
[98510] | 415 | uQuotient, uRemainder, g_aDivU[i].uQuotient, g_aDivU[i].uRemainder);
|
---|
[98496] | 416 | }
|
---|
| 417 |
|
---|
[98512] | 418 | /*
|
---|
[98496] | 419 | * Same but with random values via uint64.
|
---|
| 420 | */
|
---|
| 421 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 422 | {
|
---|
| 423 | RTUINT64U const uDividend = { RTRandU64Ex(0, i & 7 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 424 | RTUINT64U const uDivisor = { RTRandU64Ex(0, i & 3 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 425 | uint64_t const uResult = uDividend.u / uDivisor.u;
|
---|
| 426 | RTUINT64U uExpected;
|
---|
| 427 | RTUInt64Div(&uExpected, &uDividend, &uDivisor);
|
---|
| 428 | if (uResult != uExpected.u)
|
---|
| 429 | RTTestFailed(g_hTest, "%#018RX64 / %#018RX64 => %#018RX64, expected %#018RX64", uDividend.u, uDivisor.u, uResult, uExpected.u);
|
---|
| 430 | }
|
---|
| 431 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 432 | {
|
---|
| 433 | RTUINT64U const uDividend = { RTRandU64Ex(0, i & 7 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 434 | RTUINT64U const uDivisor = { RTRandU64Ex(0, i & 3 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 435 | uint64_t const uResult = uDividend.u % uDivisor.u;
|
---|
| 436 | RTUINT64U uExpected;
|
---|
| 437 | RTUInt64Mod(&uExpected, &uDividend, &uDivisor);
|
---|
| 438 | if (uResult != uExpected.u)
|
---|
| 439 | RTTestFailed(g_hTest, "%#018RX64 %% %#018RX64 => %#018RX64, expected %#018RX64", uDividend.u, uDivisor.u, uResult, uExpected.u);
|
---|
| 440 | }
|
---|
[98510] | 441 | for (uint64_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
[98496] | 442 | {
|
---|
[98510] | 443 | RTUINT64U const uDividend = { RTRandU64Ex(0, i & 7 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 444 | RTUINT64U const uDivisor = { RTRandU64Ex(0, i & 3 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 445 | uint64_t const uRemainder = uDividend.u % uDivisor.u;
|
---|
| 446 | uint64_t const uQuotient = uDividend.u / uDivisor.u;
|
---|
[98496] | 447 | RTUINT64U uExpectedQ, uExpectedR;
|
---|
| 448 | RTUInt64DivRem(&uExpectedQ, &uExpectedR, &uDividend, &uDivisor);
|
---|
[98510] | 449 | if ( uQuotient != uExpectedQ.u
|
---|
| 450 | || uRemainder != uExpectedR.u)
|
---|
[98496] | 451 | RTTestFailed(g_hTest, "%#018RX64 / %#018RX64 => q=%#018RX64 r=%#018RX64, expected q=%#018RX64 r=%#018RX64",
|
---|
[98510] | 452 | uDividend.u, uDivisor.u, uQuotient, uRemainder, uExpectedQ.u, uExpectedR.u);
|
---|
[98496] | 453 | }
|
---|
| 454 | }
|
---|
| 455 |
|
---|
| 456 |
|
---|
| 457 | TSTRTNOCRT5DIV volatile const g_aDivS[] =
|
---|
| 458 | {
|
---|
| 459 | { UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000001), /* => */ UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000) },
|
---|
| 460 | { UINT64_C(0x0000000000000000), UINT64_C(0xffffffffffffffff), /* => */ UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000) },
|
---|
| 461 |
|
---|
| 462 | { UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000001), /* => */ UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000000) },
|
---|
| 463 | { UINT64_C(0x0000000000000001), UINT64_C(0xffffffffffffffff), /* => */ UINT64_C(0xffffffffffffffff), UINT64_C(0x0000000000000000) },
|
---|
| 464 | { UINT64_C(0xffffffffffffffff), UINT64_C(0x0000000000000001), /* => */ UINT64_C(0xffffffffffffffff), UINT64_C(0x0000000000000000) },
|
---|
| 465 | { UINT64_C(0xffffffffffffffff), UINT64_C(0xffffffffffffffff), /* => */ UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000000) },
|
---|
| 466 |
|
---|
| 467 | { UINT64_C(0x0000000000000002), UINT64_C(0x0000000000000002), /* => */ UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000000) },
|
---|
| 468 |
|
---|
| 469 | { UINT64_C(0x0000000000000003), UINT64_C(0x0000000000000002), /* => */ UINT64_C(0x0000000000000001), UINT64_C(0x0000000000000001) },
|
---|
| 470 | { UINT64_C(0xfffffffffffffffd), UINT64_C(0x0000000000000002), /* => */ UINT64_C(0xffffffffffffffff), UINT64_C(0xffffffffffffffff) },
|
---|
| 471 | { UINT64_C(0x0000000000000003), UINT64_C(0xfffffffffffffffe), /* => */ UINT64_C(0xffffffffffffffff), UINT64_C(0x0000000000000001) },
|
---|
| 472 | { UINT64_C(0xfffffffffffffffd), UINT64_C(0xfffffffffffffffe), /* => */ UINT64_C(0x0000000000000001), UINT64_C(0xffffffffffffffff) },
|
---|
[98510] | 473 |
|
---|
| 474 | { UINT64_C(0x8000000000000001), UINT64_C(0x0000000000000001), /* => */ UINT64_C(0x8000000000000001), UINT64_C(0x0000000000000000) },
|
---|
| 475 | { UINT64_C(0x8000000000000001), UINT64_C(0x0000000000000002), /* => */ UINT64_C(0xc000000000000001), UINT64_C(0xffffffffffffffff) },
|
---|
| 476 | { UINT64_C(0x8000000000000001), UINT64_C(0x0000000000000002), /* => */ UINT64_C(0xc000000000000001), UINT64_C(0xffffffffffffffff) },
|
---|
| 477 |
|
---|
| 478 | { UINT64_C(0x8000000000000000), UINT64_C(0x0000000000000001), /* => */ UINT64_C(0x8000000000000000), UINT64_C(0x0000000000000000) },
|
---|
| 479 | { UINT64_C(0x8000000000000000), UINT64_C(0x0000000000000002), /* => */ UINT64_C(0xc000000000000000), UINT64_C(0x0000000000000000) },
|
---|
| 480 | { UINT64_C(0x8000000000000000), UINT64_C(0xffffffffffffffff), /* => */ UINT64_C(0x8000000000000000), UINT64_C(0x0000000000000000) },
|
---|
| 481 | { UINT64_C(0x8000000000000000), UINT64_C(0xfffffffffffffffe), /* => */ UINT64_C(0x4000000000000000), UINT64_C(0x0000000000000000) },
|
---|
[98496] | 482 | };
|
---|
| 483 |
|
---|
| 484 | static void tstSignedDivision()
|
---|
| 485 | {
|
---|
| 486 | RTTestSub(g_hTest, "64-bit signed division");
|
---|
| 487 |
|
---|
| 488 | /*
|
---|
| 489 | * static tests from array.
|
---|
| 490 | */
|
---|
| 491 | for (size_t i = 0; i < RT_ELEMENTS(g_aDivS); i++)
|
---|
| 492 | {
|
---|
| 493 | int64_t const iResult = (int64_t)g_aDivS[i].uDividend / (int64_t)g_aDivS[i].uDivisor; /* aulldiv */
|
---|
| 494 | if ((uint64_t)iResult != g_aDivS[i].uQuotient)
|
---|
| 495 | RTTestFailed(g_hTest, "i=%u %#018RX64 / %#018RX64 => %#018RX64, expected %#018RX64",
|
---|
| 496 | i, g_aDivS[i].uDividend, g_aDivS[i].uDivisor, iResult, g_aDivS[i].uQuotient);
|
---|
| 497 | }
|
---|
| 498 | for (size_t i = 0; i < RT_ELEMENTS(g_aDivS); i++)
|
---|
| 499 | {
|
---|
| 500 | int64_t const iResult = (int64_t)g_aDivS[i].uDividend % (int64_t)g_aDivS[i].uDivisor; /* aullrem */
|
---|
[98510] | 501 | if ((uint64_t)iResult != g_aDivS[i].uRemainder)
|
---|
[98496] | 502 | RTTestFailed(g_hTest, "i=%u %#018RX64 %% %#018RX64 => %#018RX64, expected %#018RX64",
|
---|
[98510] | 503 | i, g_aDivS[i].uDividend, g_aDivS[i].uDivisor, iResult, g_aDivS[i].uRemainder);
|
---|
[98496] | 504 | }
|
---|
| 505 | for (size_t i = 0; i < RT_ELEMENTS(g_aDivS); i++)
|
---|
| 506 | {
|
---|
[98510] | 507 | int64_t const iDividend = (int64_t)g_aDivS[i].uDividend;
|
---|
| 508 | int64_t const iDivisor = (int64_t)g_aDivS[i].uDivisor;
|
---|
| 509 | int64_t const iQuotient = iDividend / iDivisor; /* auldvrm hopefully - only not in unoptimized builds. */
|
---|
| 510 | int64_t const iRemainder = iDividend % iDivisor;
|
---|
| 511 | if ( (uint64_t)iQuotient != g_aDivS[i].uQuotient
|
---|
| 512 | || (uint64_t)iRemainder != g_aDivS[i].uRemainder)
|
---|
[98496] | 513 | RTTestFailed(g_hTest, "i=%u %#018RX64 / %#018RX64 => q=%#018RX64 r=%#018RX64, expected q=%#018RX64 r=%#018RX64",
|
---|
| 514 | i, g_aDivS[i].uDividend, g_aDivS[i].uDivisor,
|
---|
[98510] | 515 | iQuotient, iRemainder, g_aDivS[i].uQuotient, g_aDivS[i].uRemainder);
|
---|
[98496] | 516 | }
|
---|
| 517 |
|
---|
| 518 | /* Check that uint64 works: */
|
---|
| 519 | {
|
---|
| 520 | RTUINT64U Tmp = { 42 };
|
---|
| 521 | RTTEST_CHECK(g_hTest, !RTUInt64IsSigned(&Tmp));
|
---|
| 522 | RTUInt64AssignNeg(&Tmp);
|
---|
| 523 | int64_t iExpect = -42;
|
---|
| 524 | RTTEST_CHECK(g_hTest, Tmp.u == (uint64_t)iExpect);
|
---|
| 525 | RTTEST_CHECK(g_hTest, RTUInt64IsSigned(&Tmp));
|
---|
| 526 | }
|
---|
| 527 |
|
---|
| 528 | /*
|
---|
| 529 | * Same but with random values via uint64.
|
---|
| 530 | */
|
---|
| 531 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 532 | {
|
---|
| 533 | RTUINT64U const uDividend = { RTRandU64Ex(0, i & 7 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 534 | RTUINT64U const uDivisor = { RTRandU64Ex(1, i & 3 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 535 | int64_t const iResult = (int64_t)uDividend.u / (int64_t)uDivisor.u;
|
---|
| 536 | RTUINT64U uExpected;
|
---|
| 537 | RTUInt64DivSigned(&uExpected, &uDividend, &uDivisor);
|
---|
| 538 | if ((uint64_t)iResult != uExpected.u)
|
---|
| 539 | RTTestFailed(g_hTest, "%#018RX64 / %#018RX64 => %#018RX64, expected %#018RX64", uDividend.u, uDivisor.u, iResult, uExpected.u);
|
---|
| 540 | }
|
---|
| 541 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 542 | {
|
---|
| 543 | RTUINT64U const uDividend = { RTRandU64Ex(0, i & 7 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 544 | RTUINT64U const uDivisor = { RTRandU64Ex(1, i & 3 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 545 | int64_t const iResult = (int64_t)uDividend.u % (int64_t)uDivisor.u;
|
---|
| 546 | RTUINT64U uExpected;
|
---|
| 547 | RTUInt64ModSigned(&uExpected, &uDividend, &uDivisor);
|
---|
| 548 | if ((uint64_t)iResult != uExpected.u)
|
---|
| 549 | RTTestFailed(g_hTest, "%#018RX64 %% %#018RX64 => %#018RX64, expected %#018RX64", uDividend.u, uDivisor.u, iResult, uExpected.u);
|
---|
| 550 | }
|
---|
| 551 | for (size_t i = 0; i < RANDOM_LOOPS; i++)
|
---|
| 552 | {
|
---|
[98510] | 553 | RTUINT64U const uDividend = { RTRandU64Ex(0, i & 7 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 554 | RTUINT64U const uDivisor = { RTRandU64Ex(1, i & 3 ? UINT64_MAX : UINT32_MAX) };
|
---|
| 555 | int64_t const iRemainder = (int64_t)uDividend.u % (int64_t)uDivisor.u;
|
---|
| 556 | int64_t const iQuotient = (int64_t)uDividend.u / (int64_t)uDivisor.u;
|
---|
[98496] | 557 | RTUINT64U uExpectedQ, uExpectedR;
|
---|
| 558 | RTUInt64DivRemSigned(&uExpectedQ, &uExpectedR, &uDividend, &uDivisor);
|
---|
[98510] | 559 | if ( (uint64_t)iQuotient != uExpectedQ.u
|
---|
| 560 | || (uint64_t)iRemainder != uExpectedR.u)
|
---|
[98496] | 561 | RTTestFailed(g_hTest, "%#018RX64 / %#018RX64 => q=%#018RX64 r=%#018RX64, expected q=%#018RX64 r=%#018RX64",
|
---|
[98510] | 562 | uDividend.u, uDivisor.u, iQuotient, iRemainder, uExpectedQ.u, uExpectedR.u);
|
---|
[98496] | 563 | }
|
---|
| 564 | }
|
---|
| 565 |
|
---|
| 566 |
|
---|
| 567 | int main()
|
---|
| 568 | {
|
---|
| 569 | RTEXITCODE rcExit = RTTestInitAndCreate("tstRTNoCrt-5", &g_hTest);
|
---|
| 570 | if (rcExit != RTEXITCODE_SUCCESS)
|
---|
| 571 | return rcExit;
|
---|
| 572 | tstShiftRight();
|
---|
| 573 | tstShiftRightArithmetic();
|
---|
| 574 | tstShiftLeft();
|
---|
| 575 | tstMultiplication();
|
---|
| 576 | tstUnsignedDivision();
|
---|
| 577 | tstSignedDivision();
|
---|
| 578 |
|
---|
| 579 | return RTTestSummaryAndDestroy(g_hTest);
|
---|
| 580 | }
|
---|
| 581 |
|
---|