From dc3f97667ce316d50b03a6fe59443b85758443f1 Mon Sep 17 00:00:00 2001 From: ExpandingMan Date: Fri, 22 Nov 2019 12:39:44 -0500 Subject: [PATCH 1/4] package modernization including better type stability --- .travis.yml | 25 --------- Project.toml | 4 +- src/Decimals.jl | 45 ++++++++-------- src/arithmetic.jl | 11 ++-- src/decimal.jl | 16 ++++-- src/equals.jl | 8 +-- src/round.jl | 4 +- test/runtests.jl | 12 ++--- test/test_arithmetic.jl | 21 ++++---- test/test_constructor.jl | 2 +- test/test_decimal.jl | 109 +++++++++++++++++++-------------------- test/test_equals.jl | 44 ++++++++-------- test/test_norm.jl | 16 +++--- 13 files changed, 148 insertions(+), 169 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2806874..0000000 --- a/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -language: julia - -notifications: - email: false - -julia: - - 1.0 - - 1.2 - - 1.3 - - nightly - -matrix: - fast_finish: true - allow_failures: - - julia: nightly - -after_success: - - | - julia -e ' - using Pkg - Pkg.add("Coverage") - using Coverage - Coveralls.submit(Coveralls.process_folder()) - Codecov.submit(process_folder()) - ' diff --git a/Project.toml b/Project.toml index 1609e13..5957060 100644 --- a/Project.toml +++ b/Project.toml @@ -1,9 +1,9 @@ name = "Decimals" uuid = "abce61dc-4473-55a0-ba07-351d65e31d42" -version = "0.4.1" +version = "0.5.0" [compat] -julia = "0.7, 1" +julia = "1" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/Decimals.jl b/src/Decimals.jl index a62458d..04cb620 100644 --- a/src/Decimals.jl +++ b/src/Decimals.jl @@ -3,35 +3,36 @@ # @author jack@tinybike.net (Jack Peterson), 7/3/2014 module Decimals - import Base: ==, +, -, *, /, <, <=, float, inv, round, trunc - export Decimal, - decimal, - number, - normalize +export Decimal, + decimal, + number, + normalize - const DIGITS = 20 +const DIGITS = 20 - # Numerical value: (-1)^s * c * 10^q - struct Decimal <: AbstractFloat - s::Integer # sign can be 0 (+) or 1 (-) - c::BigInt # coefficient (significand), must be non-negative - q::Integer # exponent - end +# Numerical value: (-1)^s * c * 10^q +struct Decimal <: AbstractFloat + s::Bool # sign can be 0 (+) or 1 (-) + c::BigInt # coefficient (significand), must be non-negative + q::Int # exponent - # Convert between Decimal objects, numbers, and strings - include("decimal.jl") + Decimal(s::Integer, c::Integer, e::Integer) = new(Bool(s), c, e) +end + +# Convert between Decimal objects, numbers, and strings +include("decimal.jl") - # Decimal normalization - include("norm.jl") +# Decimal normalization +include("norm.jl") - # Addition, subtraction, negation, multiplication - include("arithmetic.jl") +# Addition, subtraction, negation, multiplication +include("arithmetic.jl") - # Equality - include("equals.jl") +# Equality +include("equals.jl") - # Rounding - include("round.jl") +# Rounding +include("round.jl") end diff --git a/src/arithmetic.jl b/src/arithmetic.jl index 7f7be79..24f496c 100644 --- a/src/arithmetic.jl +++ b/src/arithmetic.jl @@ -22,28 +22,27 @@ function +(x::Decimal, y::Decimal) c = (-1)^x.s * x.c * BigTen^q + (-1)^y.s * y.c s = signbit(c) return normalize(Decimal(s, abs(c), y.q)) -end # Negation --(x::Decimal) = Decimal((x.s == 1) ? 0 : 1, x.c, x.q) +Base.:(-)(x::Decimal) = Decimal((x.s == 1) ? 0 : 1, x.c, x.q) # Subtraction --(x::Decimal, y::Decimal) = +(x, -y) +Base.:(-)(x::Decimal, y::Decimal) = +(x, -y) # Multiplication -function *(x::Decimal, y::Decimal) +function Base.:(*)(x::Decimal, y::Decimal) s = (x.s == y.s) ? 0 : 1 normalize(Decimal(s, BigInt(x.c) * BigInt(y.c), x.q + y.q)) end # Inversion function Base.inv(x::Decimal) - c = round(BigInt(10)^(-x.q + DIGITS) / x.c) # the decimal point of 1/x.c is shifted by -x.q so that the integer part of the result is correct and then it is shifted further by DIGITS to also cover some digits from the fractional part. + c = round(BigInt, BigInt(10)^(-x.q + DIGITS) / x.c) # the decimal point of 1/x.c is shifted by -x.q so that the integer part of the result is correct and then it is shifted further by DIGITS to also cover some digits from the fractional part. q = -DIGITS # we only need to remember that there are these digits after the decimal point normalize(Decimal(x.s, c, q)) end # Division -/(x::Decimal, y::Decimal) = x * inv(y) +Base.:(/)(x::Decimal, y::Decimal) = x * inv(y) # TODO exponentiation diff --git a/src/decimal.jl b/src/decimal.jl index 65f5f4b..d5df4a1 100644 --- a/src/decimal.jl +++ b/src/decimal.jl @@ -1,10 +1,12 @@ # Convert a string to a decimal, e.g. "0.01" -> Decimal(0, 1, -2) function Base.parse(::Type{Decimal}, str::AbstractString) - if 'e' in str + if 'e' ∈ str return parse(Decimal, scinote(str)) + elseif 'E' ∈ str + return parse(Decimal, scinote(lowercase(str))) end c, q = parameters(('.' in str) ? split(str, '.') : str) - normalize(Decimal((str[1] == '-') ? 1 : 0, c, q)) + normalize(Decimal((str[1] == '-'), c, q)) end decimal(str::AbstractString) = parse(Decimal, str) @@ -60,8 +62,10 @@ function Base.print(io::IO, x::Decimal) end # Zero/one value -Base.zero(::Type{Decimal}) = Decimal(0,0,0) -Base.one(::Type{Decimal}) = Decimal(0,1,0) +Base.zero(::Type{Decimal}) = Decimal(false,0,0) +Base.one(::Type{Decimal}) = Decimal(false,1,0) + +Base.float(x::Decimal) = parse(Float64, string(x)) # convert a decimal to any subtype of Real (::Type{T})(x::Decimal) where {T<:Real} = parse(T, string(x)) @@ -73,4 +77,6 @@ function number(x::Decimal) end # sign -Base.signbit(x::Decimal) = x.s != 0 +Base.signbit(x::Decimal) = x.s + +Base.show(io::IO, x::Decimal) = write(io, "decimal(\""*string(x)*"\")") diff --git a/src/equals.jl b/src/equals.jl index 47cbeb9..c46a665 100644 --- a/src/equals.jl +++ b/src/equals.jl @@ -2,7 +2,7 @@ # equals() now depends on == instead # of the other way round. -function ==(x::Decimal, y::Decimal) +function Base.:(==)(x::Decimal, y::Decimal) # return early on zero x_is_zero = iszero(x) y_is_zero = iszero(y) @@ -17,7 +17,7 @@ end Base.iszero(x::Decimal) = iszero(x.c) -function <(x::Decimal, y::Decimal) +function Base.:(<)(x::Decimal, y::Decimal) # return early on zero if iszero(x) && iszero(y) return false @@ -46,8 +46,8 @@ end # Special case equality with AbstractFloat to allow comparison against Inf/Nan # which are not representable in Decimal -==(a::AbstractFloat, b::Decimal) = b == a -function ==(a::Decimal, b::AbstractFloat) +Base.:(==)(a::AbstractFloat, b::Decimal) = b == a +function Base.:(==)(a::Decimal, b::AbstractFloat) # Decimal does not represent NaN/Inf (isinf(b) || isnan(b)) && return false ==(promote(a, b)...) diff --git a/src/round.jl b/src/round.jl index 642485a..e6b1614 100644 --- a/src/round.jl +++ b/src/round.jl @@ -1,5 +1,5 @@ # Rounding -function round(x::Decimal; digits::Int=0, normal::Bool=false) +function Base.round(x::Decimal; digits::Int=0, normal::Bool=false) shift = BigInt(digits) + x.q if shift > BigInt(0) || shift < x.q (normal) ? x : normalize(x, rounded=true) @@ -10,7 +10,7 @@ function round(x::Decimal; digits::Int=0, normal::Bool=false) end end -function trunc(x::Decimal; digits::Int=0, normal::Bool=false) +function Base.trunc(x::Decimal; digits::Int=0, normal::Bool=false) shift = BigInt(digits) + x.q if shift > BigInt(0) || shift < x.q (normal) ? x : normalize(x, rounded=true) diff --git a/test/runtests.jl b/test/runtests.jl index 246119d..6da70af 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,12 +4,12 @@ using Test @testset "Decimals" begin global d = [ - Decimal(0, 2, -1) - Decimal(0, 1, -1) - Decimal(0, 100, -4) - Decimal(0, 1512, -2) - Decimal(1, 3, -2) - Decimal(1, 4, -6) + Decimal(false, 2, -1) + Decimal(false, 1, -1) + Decimal(false, 100, -4) + Decimal(false, 1512, -2) + Decimal(true, 3, -2) + Decimal(true, 4, -6) ] include("test_constructor.jl") diff --git a/test/test_arithmetic.jl b/test/test_arithmetic.jl index 952088c..c07413d 100644 --- a/test/test_arithmetic.jl +++ b/test/test_arithmetic.jl @@ -7,8 +7,7 @@ using Test @test Decimal(0.1) + 0.2 == 0.1 + Decimal(0.2) == Decimal(0.1) + Decimal(0.2) == Decimal(0.3) @test Decimal.([0.1 0.2]) .+ [0.3 0.1] == Decimal.([0.4 0.3]) @test Decimal(2147483646) + Decimal(1) == Decimal(2147483647) - @test Decimal(1,3,-2) + parse(Decimal, "0.2523410412138103") == Decimal(0,2223410412138103,-16) - + @test Decimal(1,3,-2) + parse(Decimal, "0.2523410412138103") == Decimal(false,2223410412138103,-16) @test Decimal(0, 10000000000000000001, -19) + Decimal(0, 1, 0) == Decimal(0, 20000000000000000001, -19) end @@ -40,15 +39,15 @@ end end @testset "Inversion" begin - @test inv(Decimal(0, 1, -1)) == Decimal(0, 1, 1) - @test inv(Decimal(0, 1, 1)) == Decimal(0, 1, -1) - @test inv(Decimal(1, 2, -1)) == Decimal(1, 5, 0) - @test inv(Decimal(1, 5, 0)) == Decimal(1, 2, -1) - @test inv(Decimal(0, 2, -2)) == Decimal(0, 5, 1) - @test inv(Decimal(0, 5, 1)) == Decimal(0, 2, -2) - @test inv(Decimal(1, 4, -1)) == Decimal(1, 25, -1) - @test inv(Decimal(1, 25, -1)) == Decimal(1, 4, -1) - @test inv(Decimal(0, 123, -1)) == Decimal(0, 813008130081300813, -19) # 1/12.3 ≈ 0.08 + @test inv(Decimal(false, 1, -1)) == Decimal(false, 1, 1) + @test inv(Decimal(false, 1, 1)) == Decimal(false, 1, -1) + @test inv(Decimal(true, 2, -1)) == Decimal(true, 5, 0) + @test inv(Decimal(true, 5, 0)) == Decimal(true, 2, -1) + @test inv(Decimal(false, 2, -2)) == Decimal(false, 5, 1) + @test inv(Decimal(false, 5, 1)) == Decimal(false, 2, -2) + @test inv(Decimal(true, 4, -1)) == Decimal(true, 25, -1) + @test inv(Decimal(true, 25, -1)) == Decimal(true, 4, -1) + @test inv(Decimal(false, 123, -1)) == Decimal(false, 813008130081300813, -19) # 1/12.3 ≈ 0.08 end @testset "Division" begin diff --git a/test/test_constructor.jl b/test/test_constructor.jl index 95970cd..fb82d73 100644 --- a/test/test_constructor.jl +++ b/test/test_constructor.jl @@ -3,6 +3,6 @@ using Test @testset "Decimal constructor" begin -@test isa(d, Array{Decimal,1}) +@test d isa Vector{Decimal} end diff --git a/test/test_decimal.jl b/test/test_decimal.jl index cb2652e..e7602b3 100644 --- a/test/test_decimal.jl +++ b/test/test_decimal.jl @@ -5,34 +5,33 @@ using Test @testset "String/Number to Decimal" begin @testset "Direct" begin - @test parse(Decimal, "0.01") == Decimal(0.01) == Decimal(0, 1, -2) - @test parse(Decimal, ".001") == Decimal(.001) == Decimal(0, 1, -3) - @test parse(Decimal, "15.23") == Decimal(15.23) == Decimal(0, 1523, -2) - @test parse(Decimal, "543") == Decimal(543) == Decimal(0, 543, 0) - @test parse(Decimal, "-345") == Decimal(-345) == Decimal(1, 345, 0) - @test parse(Decimal, "000123") == Decimal(000123) == Decimal(0, 123, 0) - @test parse(Decimal, "-00032") == Decimal(-00032) == Decimal(1, 32, 0) - @test parse(Decimal, "200100") == Decimal(200100) == Decimal(0, 2001, 2) - @test parse(Decimal, "-.123") == Decimal(-.123) == Decimal(1, 123, -3) - @test parse(Decimal, "1.23000") == Decimal(1.23000) == Decimal(0, 123, -2) - @test parse(Decimal, "4734.612") == Decimal(4734.612) == Decimal(0, 4734612, -3) - @test parse(Decimal, "541724.2") == Decimal(541724.2) == Decimal(0,5417242,-1) - @test parse(Decimal, "1e0") == Decimal(0, 1, 0) - @test parse(Decimal, "2.5e6") == Decimal(2.5e6) == Decimal(0, 25, 5) - @test parse(Decimal, "2.385350e8") == Decimal(2.385350e8) == Decimal(0, 238535, 3) - @test parse(Decimal, "12.3e-4") == Decimal(12.3e-4) == Decimal(0, 123, -5) + @test parse(Decimal, "0.01") == Decimal(0.01) == Decimal(false, 1, -2) + @test parse(Decimal, ".001") == Decimal(.001) == Decimal(false, 1, -3) + @test parse(Decimal, "15.23") == Decimal(15.23) == Decimal(false, 1523, -2) + @test parse(Decimal, "543") == Decimal(543) == Decimal(false, 543, 0) + @test parse(Decimal, "-345") == Decimal(-345) == Decimal(true, 345, 0) + @test parse(Decimal, "000123") == Decimal(000123) == Decimal(false, 123, 0) + @test parse(Decimal, "-00032") == Decimal(-00032) == Decimal(true, 32, 0) + @test parse(Decimal, "200100") == Decimal(200100) == Decimal(false, 2001, 2) + @test parse(Decimal, "-.123") == Decimal(-.123) == Decimal(true, 123, -3) + @test parse(Decimal, "1.23000") == Decimal(1.23000) == Decimal(false, 123, -2) + @test parse(Decimal, "4734.612") == Decimal(4734.612) == Decimal(false, 4734612, -3) + @test parse(Decimal, "541724.2") == Decimal(541724.2) == Decimal(false,5417242,-1) + @test parse(Decimal, "2.5e6") == Decimal(2.5e6) == Decimal(false, 25, 5) + @test parse(Decimal, "2.385350e8") == Decimal(2.385350e8) == Decimal(false, 238535, 3) + @test parse(Decimal, "12.3e-4") == Decimal(12.3e-4) == Decimal(false, 123, -5) - @test parse(Decimal, "-12.3e4") == Decimal(-12.3e4) == Decimal(1, 123, 3) + @test parse(Decimal, "-12.3e4") == Decimal(-12.3e4) == Decimal(true, 123, 3) - @test parse(Decimal, "-12.3e-4") == Decimal(-12.3e-4) == Decimal(1, 123, -5) + @test parse(Decimal, "-12.3e-4") == Decimal(-12.3e-4) == Decimal(true, 123, -5) - @test parse(Decimal, "0.1234567891") == Decimal(0.1234567891) == Decimal(0,1234567891, -10) - @test parse(Decimal, "0.12345678912") == Decimal(0.12345678912) == Decimal(0,12345678912, -11) + @test parse(Decimal, "0.1234567891") == Decimal(0.1234567891) == Decimal(false,1234567891, -10) + @test parse(Decimal, "0.12345678912") == Decimal(0.12345678912) == Decimal(false,12345678912, -11) end @testset "Using `decimal`" begin - @test decimal("1.0") == Decimal(0, 1, 0) - @test decimal(8.1) == Decimal(0, 81, -1) + @test decimal("1.0") == Decimal(false, 1, 0) + @test decimal(8.1) == Decimal(false, 81, -1) @test decimal.(Float64.(d)) == d end end @@ -42,42 +41,42 @@ end end @testset "Decimal to String" begin - @test string(Decimal(0, 1, -2)) == "0.01" - @test string(Decimal(0, 1, -3)) == "0.001" - @test string(Decimal(0, 1523, -2)) == "15.23" - @test string(Decimal(0, 543, 0)) == "543" - @test string(Decimal(1, 345, 0)) == "-345" - @test string(Decimal(0, 123, 0)) == "123" - @test string(Decimal(1, 32, 0)) == "-32" - @test string(Decimal(0, 2001, 2)) == "200100" - @test string(Decimal(1, 123, -3)) == "-0.123" - @test string(Decimal(0, 123, -2)) == "1.23" + @test string(Decimal(false, 1, -2)) == "0.01" + @test string(Decimal(false, 1, -3)) == "0.001" + @test string(Decimal(false, 1523, -2)) == "15.23" + @test string(Decimal(false, 543, 0)) == "543" + @test string(Decimal(true, 345, 0)) == "-345" + @test string(Decimal(false, 123, 0)) == "123" + @test string(Decimal(true, 32, 0)) == "-32" + @test string(Decimal(false, 2001, 2)) == "200100" + @test string(Decimal(true, 123, -3)) == "-0.123" + @test string(Decimal(false, 123, -2)) == "1.23" end @testset "Decimal to Number" begin - @test Float32(Decimal(0, 1, -2)) == 0.01f0 - @test Float64(Decimal(0, 1, -3)) == 0.001 - @test Float64(Decimal(0, 1523, -2)) == 15.23 - @test UInt(Decimal(0, 543, 0)) == 543 - @test Int(Decimal(1, 345, 0)) == -345 - @test Int32(Decimal(0, 123, 0)) == 123 - @test Int8(Decimal(1, 32, 0)) == -32 - @test BigInt(Decimal(0, 2001, 2)) == 200100 - @test BigFloat(Decimal(1, 123, -3)) == big"-0.123" - @test Float64(Decimal(0, 123, -2)) == 1.23 - @test number(Decimal(0, 1, -2)) == 0.01 - @test number(Decimal(0, 1, -3)) == 0.001 - @test number(Decimal(0, 1523, -2)) == 15.23 - @test number(Decimal(0, 543, 0)) == 543 - @test number(Decimal(1, 345, 0)) == -345 - @test number(Decimal(0, 123, 0)) == 123 - @test number(Decimal(1, 32, 0)) == -32 - @test number(Decimal(0, 2001, 2)) == 200100 - @test number(Decimal(1, 123, -3)) == -0.123 - @test number(Decimal(0, 123, -2)) == 1.23 - @test string(Float64(Decimal(0, 543, 0))) == "543.0" - @test string(number(Decimal(0, 543, 0))) == "543" - @test string(number(Decimal(0, 543, -1))) == "54.3" + @test Float32(Decimal(false, 1, -2)) == 0.01f0 + @test Float64(Decimal(false, 1, -3)) == 0.001 + @test Float64(Decimal(false, 1523, -2)) == 15.23 + @test UInt(Decimal(false, 543, 0)) == 543 + @test Int(Decimal(true, 345, 0)) == -345 + @test Int32(Decimal(false, 123, 0)) == 123 + @test Int8(Decimal(true, 32, 0)) == -32 + @test BigInt(Decimal(false, 2001, 2)) == 200100 + @test BigFloat(Decimal(true, 123, -3)) == big"-0.123" + @test Float64(Decimal(false, 123, -2)) == 1.23 + @test number(Decimal(false, 1, -2)) == 0.01 + @test number(Decimal(false, 1, -3)) == 0.001 + @test number(Decimal(false, 1523, -2)) == 15.23 + @test number(Decimal(false, 543, 0)) == 543 + @test number(Decimal(true, 345, 0)) == -345 + @test number(Decimal(false, 123, 0)) == 123 + @test number(Decimal(true, 32, 0)) == -32 + @test number(Decimal(false, 2001, 2)) == 200100 + @test number(Decimal(true, 123, -3)) == -0.123 + @test number(Decimal(false, 123, -2)) == 1.23 + @test string(Float64(Decimal(false, 543, 0))) == "543.0" + @test string(number(Decimal(false, 543, 0))) == "543" + @test string(number(Decimal(false, 543, -1))) == "54.3" end end diff --git a/test/test_equals.jl b/test/test_equals.jl index 64108be..07c6529 100644 --- a/test/test_equals.jl +++ b/test/test_equals.jl @@ -4,24 +4,24 @@ using Test @testset "Equality" begin @testset "isequal" begin - @test isequal(Decimal(0, 2, -3), Decimal(0, 2, -3)) - @test !isequal(Decimal(0, 2, -3), Decimal(0, 2, 3)) - @test isequal(Decimal(0, 2, -3), 0.002) - @test isequal(Decimal(1, 2, 0), -2) - @test !isequal(Decimal(1, 2, 0), 2) - @test !isequal(Decimal(1, 0, -1), Decimal(0, 0, 0)) + @test isequal(Decimal(false, 2, -3), Decimal(false, 2, -3)) + @test !isequal(Decimal(false, 2, -3), Decimal(false, 2, 3)) + @test isequal(Decimal(false, 2, -3), 0.002) + @test isequal(Decimal(true, 2, 0), -2) + @test !isequal(Decimal(true, 2, 0), 2) + @test !isequal(Decimal(true, 0, -1), Decimal(false, 0, 0)) end @testset "==" begin - @test Decimal(0, 2, -3) == Decimal(0, 2, -3) - @test Decimal(0, 2, -3) != Decimal(0, 2, 3) - @test Decimal(0, 2, -3) == 0.002 + @test Decimal(false, 2, -3) == Decimal(false, 2, -3) + @test Decimal(false, 2, -3) != Decimal(false, 2, 3) + @test Decimal(false, 2, -3) == 0.002 - @test -2 == Decimal(1, 2, 0) - @test 2 != Decimal(1, 2, 0) + @test -2 == Decimal(true, 2, 0) + @test 2 != Decimal(true, 2, 0) - @test Decimal(1, 2, 0) == -2 - @test Decimal(1, 2, 0) != 2 + @test Decimal(true, 2, 0) == -2 + @test Decimal(true, 2, 0) != 2 bf_pi = BigFloat(pi) @test Decimal(bf_pi) == bf_pi @@ -33,19 +33,19 @@ end @test decimal(12.1) == decimal(12.1) - @test Decimal(1, 0, -1) == Decimal(0, 0, 0) + @test Decimal(true, 0, -1) == Decimal(false, 0, 0) end @testset "<" begin - @test Decimal(1, 1, 1) < Decimal(0, 1, 1) - @test !(Decimal(0, 1, 1) < Decimal(1, 1, 1)) - @test Decimal(1, 1, 1) < Decimal(1, 0, 1) - @test !(Decimal(1, 0, 1) < Decimal(1, 1, 1)) - @test Decimal(0, 2, -3) < Decimal(0, 2, 3) - @test !(Decimal(0, 2, 3) < Decimal(0, 2, -3)) + @test Decimal(true, 1, 1) < Decimal(false, 1, 1) + @test !(Decimal(false, 1, 1) < Decimal(true, 1, 1)) + @test Decimal(true, 1, 1) < Decimal(true, 0, 1) + @test !(Decimal(true, 0, 1) < Decimal(true, 1, 1)) + @test Decimal(false, 2, -3) < Decimal(false, 2, 3) + @test !(Decimal(false, 2, 3) < Decimal(false, 2, -3)) @test !(decimal(12.1) < decimal(12.1)) - @test !(Decimal(1, 0, -1) < Decimal(0, 0, 0)) - @test !(Decimal(0, 0, 0) < Decimal(1, 0, -1)) + @test !(Decimal(true, 0, -1) < Decimal(false, 0, 0)) + @test !(Decimal(false, 0, 0) < Decimal(true, 0, -1)) end @testset ">" begin diff --git a/test/test_norm.jl b/test/test_norm.jl index c4b8371..2bf3413 100644 --- a/test/test_norm.jl +++ b/test/test_norm.jl @@ -3,13 +3,13 @@ using Test @testset "Normalization" begin -@test Decimal(1, 151100, -4) == Decimal(1, 1511, -2) -@test Decimal(0, 100100, -5) == Decimal(0, 1001, -3) -@test normalize(Decimal(1, 151100, -4)) == Decimal(1, 1511, -2) -@test normalize(Decimal(0, 100100, -5)) == Decimal(0, 1001, -3) -@test parse(Decimal, "3.0") == Decimal(0, 3, 0) -@test parse(Decimal, "3.0") == Decimal(0, 30, -1) -@test parse(Decimal, "3.1400") == Decimal(0, 314, -2) -@test parse(Decimal, "1234") == Decimal(0, 1234, 0) +@test Decimal(true, 151100, -4) == Decimal(true, 1511, -2) +@test Decimal(false, 100100, -5) == Decimal(false, 1001, -3) +@test normalize(Decimal(1, 151100, -4)) == Decimal(true, 1511, -2) +@test normalize(Decimal(0, 100100, -5)) == Decimal(false, 1001, -3) +@test parse(Decimal, "3.0") == Decimal(false, 3, 0) +@test parse(Decimal, "3.0") == Decimal(false, 30, -1) +@test parse(Decimal, "3.1400") == Decimal(false, 314, -2) +@test parse(Decimal, "1234") == Decimal(false, 1234, 0) end From 2fe8b447d13d1a0b6a82916910378c9b191b5d70 Mon Sep 17 00:00:00 2001 From: ExpandingMan Date: Fri, 22 Nov 2019 12:44:31 -0500 Subject: [PATCH 2/4] reduced version bounds --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 5957060..c1d9d2e 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "Decimals" uuid = "abce61dc-4473-55a0-ba07-351d65e31d42" -version = "0.5.0" +version = "0.4.1" [compat] julia = "1" From d2b95351e1d607d0982c4e41c3e5f6b70dbb59ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Baru=C4=8Di=C4=87?= Date: Tue, 15 Oct 2024 16:28:21 +0200 Subject: [PATCH 3/4] Apply suggestions from review Co-authored-by: Curtis Vogt --- src/arithmetic.jl | 7 ++++--- src/decimal.jl | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/arithmetic.jl b/src/arithmetic.jl index 24f496c..549c10b 100644 --- a/src/arithmetic.jl +++ b/src/arithmetic.jl @@ -10,7 +10,7 @@ const BigTen = BigInt(10) # To add, convert both decimals to the same exponent. # (If the exponents are different, use the smaller exponent # to make sure we're adding integers.) -function +(x::Decimal, y::Decimal) +function Base.:(+)(x::Decimal, y::Decimal) if x.q < y.q x, y = y, x end @@ -22,16 +22,17 @@ function +(x::Decimal, y::Decimal) c = (-1)^x.s * x.c * BigTen^q + (-1)^y.s * y.c s = signbit(c) return normalize(Decimal(s, abs(c), y.q)) +end # Negation -Base.:(-)(x::Decimal) = Decimal((x.s == 1) ? 0 : 1, x.c, x.q) +Base.:(-)(x::Decimal) = Decimal(!x.s, x.c, x.q) # Subtraction Base.:(-)(x::Decimal, y::Decimal) = +(x, -y) # Multiplication function Base.:(*)(x::Decimal, y::Decimal) - s = (x.s == y.s) ? 0 : 1 + s = x.s != y.s normalize(Decimal(s, BigInt(x.c) * BigInt(y.c), x.q + y.q)) end diff --git a/src/decimal.jl b/src/decimal.jl index d5df4a1..140f26a 100644 --- a/src/decimal.jl +++ b/src/decimal.jl @@ -6,7 +6,7 @@ function Base.parse(::Type{Decimal}, str::AbstractString) return parse(Decimal, scinote(lowercase(str))) end c, q = parameters(('.' in str) ? split(str, '.') : str) - normalize(Decimal((str[1] == '-'), c, q)) + normalize(Decimal(str[1] == '-', c, q)) end decimal(str::AbstractString) = parse(Decimal, str) @@ -62,8 +62,8 @@ function Base.print(io::IO, x::Decimal) end # Zero/one value -Base.zero(::Type{Decimal}) = Decimal(false,0,0) -Base.one(::Type{Decimal}) = Decimal(false,1,0) +Base.zero(::Type{Decimal}) = Decimal(false, 0, 0) +Base.one(::Type{Decimal}) = Decimal(false, 1, 0) Base.float(x::Decimal) = parse(Float64, string(x)) @@ -79,4 +79,4 @@ end # sign Base.signbit(x::Decimal) = x.s -Base.show(io::IO, x::Decimal) = write(io, "decimal(\""*string(x)*"\")") +Base.show(io::IO, x::Decimal) = write(io, "decimal(\"$x\")") From 53480223c58992a392d3abc5be528ae90ff85524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Baru=C4=8Di=C4=87?= Date: Tue, 15 Oct 2024 16:39:01 +0200 Subject: [PATCH 4/4] remove new features --- src/decimal.jl | 3 --- test/test_decimal.jl | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/decimal.jl b/src/decimal.jl index 140f26a..11da6ca 100644 --- a/src/decimal.jl +++ b/src/decimal.jl @@ -65,8 +65,6 @@ end Base.zero(::Type{Decimal}) = Decimal(false, 0, 0) Base.one(::Type{Decimal}) = Decimal(false, 1, 0) -Base.float(x::Decimal) = parse(Float64, string(x)) - # convert a decimal to any subtype of Real (::Type{T})(x::Decimal) where {T<:Real} = parse(T, string(x)) @@ -79,4 +77,3 @@ end # sign Base.signbit(x::Decimal) = x.s -Base.show(io::IO, x::Decimal) = write(io, "decimal(\"$x\")") diff --git a/test/test_decimal.jl b/test/test_decimal.jl index e7602b3..57c7c3c 100644 --- a/test/test_decimal.jl +++ b/test/test_decimal.jl @@ -24,6 +24,7 @@ using Test @test parse(Decimal, "-12.3e4") == Decimal(-12.3e4) == Decimal(true, 123, 3) @test parse(Decimal, "-12.3e-4") == Decimal(-12.3e-4) == Decimal(true, 123, -5) + @test parse(Decimal, "-12.3E-4") == Decimal(true, 123, -5) @test parse(Decimal, "0.1234567891") == Decimal(0.1234567891) == Decimal(false,1234567891, -10) @test parse(Decimal, "0.12345678912") == Decimal(0.12345678912) == Decimal(false,12345678912, -11)