Skip to content

Commit 0ebb0ce

Browse files
committed
Create new rounding mode: RoundThrows
1 parent 5a05c88 commit 0ebb0ce

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

src/FixedPointDecimals.jl

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
module FixedPointDecimals
2525

26-
export FixedDecimal
26+
export FixedDecimal, RoundThrows
2727

2828
using Compat
2929

@@ -293,8 +293,16 @@ function show{T, f}(io::IO, x::FD{T, f})
293293
end
294294

295295
# parsing
296+
297+
"""
298+
RoundThrows
299+
300+
Raises an `InexactError` if any rounding is necessary.
301+
"""
302+
const RoundThrows = RoundingMode{:Throw}()
303+
296304
function parse{T, f}(::Type{FD{T, f}}, str::AbstractString, mode::RoundingMode=RoundNearest)
297-
if !(mode in [RoundNearest, RoundToZero])
305+
if !(mode in [RoundThrows, RoundNearest, RoundToZero])
298306
throw(ArgumentError("Unhandled rounding mode $mode"))
299307
end
300308

@@ -329,9 +337,14 @@ function parse{T, f}(::Type{FD{T, f}}, str::AbstractString, mode::RoundingMode=R
329337

330338
# Parse the strings
331339
val = isempty(a) ? T(0) : sign * parse(T, a)
332-
if !isempty(b) && mode != RoundToZero
333-
val += sign * parse_round(T, b, mode)
340+
if !isempty(b) && any(collect(b[2:end]) .!= '0')
341+
if mode == RoundThrows
342+
throw(InexactError())
343+
elseif mode == RoundNearest
344+
val += sign * parse_round(T, b, mode)
345+
end
334346
end
347+
335348
reinterpret(FD{T, f}, val)
336349
end
337350

test/runtests.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,30 @@ end
520520
@test parse(FD4, "1.5e-4", RoundToZero) == reinterpret(FD4, 0_0001)
521521
end
522522

523+
@testset "round throws" begin
524+
@test parse(FD2, "0.44", RoundThrows) == reinterpret(FD2, 0_44)
525+
@test parse(FD2, "0.440", RoundThrows) == reinterpret(FD2, 0_44)
526+
527+
@test_throws InexactError parse(FD2, "0.444", RoundThrows)
528+
@test_throws InexactError parse(FD2, "0.445", RoundThrows)
529+
@test_throws InexactError parse(FD2, "0.446", RoundThrows)
530+
@test_throws InexactError parse(FD2, "0.454", RoundThrows)
531+
@test_throws InexactError parse(FD2, "0.455", RoundThrows)
532+
@test_throws InexactError parse(FD2, "0.456", RoundThrows)
533+
534+
@test_throws InexactError parse(FD2, "-0.444", RoundThrows)
535+
@test_throws InexactError parse(FD2, "-0.445", RoundThrows)
536+
@test_throws InexactError parse(FD2, "-0.446", RoundThrows)
537+
@test_throws InexactError parse(FD2, "-0.454", RoundThrows)
538+
@test_throws InexactError parse(FD2, "-0.455", RoundThrows)
539+
@test_throws InexactError parse(FD2, "-0.456", RoundThrows)
540+
541+
@test_throws InexactError parse(FD2, "0.009", RoundThrows)
542+
@test_throws InexactError parse(FD2, "-0.009", RoundThrows)
543+
544+
@test_throws InexactError parse(FD4, "1.5e-4", RoundThrows)
545+
end
546+
523547
@testset "invalid" begin
524548
@test_throws OverflowError parse(FD4, "1.2e100")
525549
@test_throws ArgumentError parse(FD4, "foo")

0 commit comments

Comments
 (0)