|
256 | 256 | @testset "division by 1" begin
|
257 | 257 | @testset for x in keyvalues[FD2]
|
258 | 258 | @test x / one(x) == x
|
259 |
| - @test x / -one(x) == -x |
| 259 | + |
| 260 | + # signed integers using two's complement have one additional negative value |
| 261 | + if x < 0 && x == typemin(x) |
| 262 | + @test_throws InexactError x / -one(x) |
| 263 | + else |
| 264 | + @test x / -one(x) == -x |
| 265 | + end |
260 | 266 | end
|
261 | 267 | end
|
262 | 268 |
|
@@ -320,24 +326,55 @@ end
|
320 | 326 | @test 129 / FD2(200) == FD2(0.64)
|
321 | 327 | @test -129 / FD2(200) == FD2(-0.64)
|
322 | 328 |
|
323 |
| - # Use of Float or BigFloat internally can change the calculated result |
324 |
| - @test round(Int, 109 / 200 * 100) == 55 |
325 |
| - @test round(Int, BigInt(109) / 200 * 100) == 54 # Correct |
326 |
| - |
327 |
| - x = FD{Int128,2}(1.09) |
328 |
| - @test x / Int128(2) != x / BigInt(2) |
329 |
| - @test x / FD{Int128,2}(2) == x / Int128(2) |
| 329 | + # Using a floating-point number internally can slightly change the result |
| 330 | + @test round(Int, 109 / 200 * 100) == 55 # Wrong |
| 331 | + @test round(Int, BigInt(109) / 200 * 100) == 54 |
| 332 | + @test round(Int, 109 // 200 * 100) == 54 |
330 | 333 |
|
331 |
| - y = FD{Int128,2}(200) |
332 |
| - @test Int128(109) / y != BigInt(109) / y |
333 |
| - @test FD{Int128,2}(109) / y == Int128(109) / y |
| 334 | + x = FD2(1.09) |
| 335 | + y = FD2(200) |
| 336 | + for T in [FD2, Int8, Int128, BigInt] |
| 337 | + @test x / T(2) == FD2(0.54) |
| 338 | + @test T(109) / y == FD2(0.54) |
| 339 | + end |
334 | 340 | end
|
335 | 341 |
|
336 | 342 | @testset "without promotion" begin
|
337 | 343 | @test_throws InexactError FD{Int8,1}(20)
|
338 | 344 | @test 20 / FD{Int8,1}(2) == FD{Int8,1}(10.0)
|
339 | 345 | @test FD{Int8,1}(2) / 20 == FD{Int8,1}(0.1)
|
340 | 346 | end
|
| 347 | + |
| 348 | + @testset "limits" begin |
| 349 | + @test_throws InexactError 1 / FD{Int8,2}(0.4) |
| 350 | + @test_throws InexactError FD{Int8,2}(1) / FD{Int8,2}(0.4) |
| 351 | + |
| 352 | + for T in CONTAINER_TYPES |
| 353 | + x = FixedPointDecimals.max_exp10(T) |
| 354 | + f = x + 1 |
| 355 | + |
| 356 | + scalar = reinterpret(FD{T,f}, T(10)^x) # 0.1 |
| 357 | + |
| 358 | + # Since multiply will round the result we'll make sure our value always |
| 359 | + # rounds down. |
| 360 | + max_int = typemax(T) - (typemax(T) % 10) |
| 361 | + min_int = typemin(T) - (typemin(T) % 10) |
| 362 | + max_fd = reinterpret(FD{T,f}, max_int) |
| 363 | + min_fd = reinterpret(FD{T,f}, min_int) |
| 364 | + |
| 365 | + @eval begin |
| 366 | + @test ($max_fd * $scalar) / $scalar == $max_fd |
| 367 | + @test ($min_fd * $scalar) / $scalar == $min_fd |
| 368 | + @test $max_fd / 2 == reinterpret(FD{$T,$f}, div($max_int, 2)) |
| 369 | + @test $min_fd / 2 == reinterpret(FD{$T,$f}, div($min_int, 2)) |
| 370 | + |
| 371 | + # Since the precision of `f` doesn't allow us to make a FixedDecimal >= 1 |
| 372 | + # there is no way testing this function without raising an exception. |
| 373 | + $max_fd != 0 && @test_throws InexactError 2 / $max_fd |
| 374 | + $min_fd != 0 && @test_throws InexactError 2 / $min_fd |
| 375 | + end |
| 376 | + end |
| 377 | + end |
341 | 378 | end
|
342 | 379 |
|
343 | 380 | @testset "abs, sign" begin
|
|
0 commit comments