-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Various Decimal usability tweaks #10517
Changes from 7 commits
5d7d552
3d7ad7e
58913e7
d2f4e7e
f230c60
4191563
7e7c44f
72cc079
ac986e2
4ad7d9c
11e2bd3
64be2e5
aaa9c67
808c8ea
bde8831
78304b9
9cddd97
3fa7cc4
a894da7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -89,7 +89,7 @@ type Decimal | |||||
Value (big_decimal : BigDecimal) | ||||||
|
||||||
## ICON input_number | ||||||
Construct a `Decimal` from a string or integer. | ||||||
Construct a `Decimal` from a string, integer or float. | ||||||
|
||||||
Arguments: | ||||||
- x: The `Text`, `Integer`, or `Float` to construct a `Decimal` from. | ||||||
|
@@ -114,11 +114,21 @@ type Decimal | |||||
Create a `Decimal` from a string. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||||||
|
||||||
c = Decimal.new "12.345" | ||||||
|
||||||
^ Example | ||||||
Create a `Decimal` from an integer. | ||||||
|
||||||
c = Decimal.new 12345 | ||||||
|
||||||
^ Example | ||||||
Create a `Decimal` from a float. | ||||||
|
||||||
c = Decimal.new 12.345 | ||||||
new : Text | Integer | Float -> Math_Context | Nothing -> Decimal ! Arithmetic_Error | Number_Parse_Error | ||||||
new (x : Text | Integer | Float) (mc : Math_Context | Nothing = Nothing) -> Decimal ! Arithmetic_Error | Number_Parse_Error = | ||||||
handle_java_exception <| | ||||||
case x of | ||||||
_ : Text -> Decimal.from_string x mc | ||||||
_ : Text -> Decimal.from_text x mc | ||||||
_ : Integer -> Decimal.from_integer x mc | ||||||
_ : Float -> Decimal.from_float x mc | ||||||
|
||||||
|
@@ -147,9 +157,9 @@ type Decimal | |||||
^ Example | ||||||
Create a `Decimal` from a string. | ||||||
|
||||||
d = Decimal.from_string "12.345" | ||||||
from_string : Text -> Math_Context | Nothing -> Decimal ! Number_Parse_Error | ||||||
from_string (s : Text) (mc : Math_Context | Nothing = Nothing) -> Decimal ! Number_Parse_Error = | ||||||
d = Decimal.from_text "12.345" | ||||||
from_text : Text -> Math_Context | Nothing -> Decimal ! Number_Parse_Error | ||||||
from_text (s : Text) (mc : Math_Context | Nothing = Nothing) -> Decimal ! Number_Parse_Error = | ||||||
handle_java_exception <| handle_number_format_exception <| | ||||||
case mc of | ||||||
_ : Math_Context -> Decimal.Value <| handle_precision_loss s <| Decimal_Utils.fromString s mc.math_context | ||||||
|
@@ -343,7 +353,7 @@ type Decimal | |||||
c = a + b | ||||||
# => Decimal.new 30.55 | ||||||
+ : Decimal -> Decimal | ||||||
+ self (that : Decimal) = self.add that | ||||||
+ self (that : Decimal) -> Decimal ! Arithmetic_Error = self.add that | ||||||
|
||||||
## ALIAS minus | ||||||
GROUP Operators | ||||||
|
@@ -402,7 +412,7 @@ type Decimal | |||||
c = a - b | ||||||
# => Decimal.new 10.11 | ||||||
- : Decimal -> Decimal | ||||||
- self (that : Decimal) = self.subtract that | ||||||
- self (that : Decimal) -> Decimal ! Arithmetic_Error = self.subtract that | ||||||
|
||||||
## ALIAS times | ||||||
GROUP Operators | ||||||
|
@@ -460,7 +470,7 @@ type Decimal | |||||
c = a * b | ||||||
# => Decimal.new 207.7726 | ||||||
* : Decimal -> Decimal | ||||||
* self (that : Decimal) = self.multiply that | ||||||
* self (that : Decimal) -> Decimal ! Arithmetic_Error = self.multiply that | ||||||
|
||||||
## GROUP Operators | ||||||
ICON math | ||||||
|
@@ -524,7 +534,7 @@ type Decimal | |||||
c = a / b | ||||||
# => Decimal.new 45.67 | ||||||
/ : Decimal -> Decimal | ||||||
/ self (that : Decimal) = self.divide that | ||||||
/ self (that : Decimal) -> Decimal ! Arithmetic_Error = self.divide that | ||||||
|
||||||
## ALIAS modulo, modulus | ||||||
GROUP Operators | ||||||
|
@@ -554,7 +564,7 @@ type Decimal | |||||
remainder = Decimal.new -5 . remainder 3 | ||||||
# => -2 | ||||||
remainder : Decimal -> Decimal | ||||||
remainder self (that : Decimal) = | ||||||
remainder self (that : Decimal) -> Decimal = | ||||||
handle_java_exception <| | ||||||
Decimal.Value (self.big_decimal.remainder that.big_decimal) | ||||||
|
||||||
|
@@ -586,7 +596,7 @@ type Decimal | |||||
remainder = Decimal.new -5 % 3 | ||||||
# => -2 | ||||||
% : Decimal -> Decimal | ||||||
% self (that : Decimal) = self.remainder that | ||||||
% self (that : Decimal) -> Decimal = self.remainder that | ||||||
|
||||||
## GROUP Math | ||||||
ICON math | ||||||
|
@@ -640,7 +650,7 @@ type Decimal | |||||
Decimal.new "2.25" . pow (Decimal.new "5") | ||||||
# => 57.6650390625 | ||||||
pow : Integer -> Decimal | ||||||
pow self exp:Integer = | ||||||
pow self exp:Integer -> Decimal = | ||||||
## If `exp` is an integer that does not fit in a Java Integer, | ||||||
UnsuppUnsupported_Argument_Types is raised, so we convert that to an | ||||||
Arithmetic_Error. | ||||||
|
@@ -667,7 +677,7 @@ type Decimal | |||||
Decimal.new "2.25" ^ Decimal.new "5" | ||||||
# => 57.6650390625 | ||||||
^ : Integer -> Decimal | ||||||
^ self exp:Integer = self.pow exp | ||||||
^ self exp:Integer -> Decimal = self.pow exp | ||||||
|
||||||
## GROUP Operators | ||||||
ICON operators | ||||||
|
@@ -679,7 +689,7 @@ type Decimal | |||||
5.1.negate | ||||||
# => Decimal.new -5.1 | ||||||
negate : Decimal | ||||||
negate self = Decimal.Value self.big_decimal.negate | ||||||
negate self -> Decimal = Decimal.Value self.big_decimal.negate | ||||||
|
||||||
## GROUP Math | ||||||
ICON math | ||||||
|
@@ -754,7 +764,7 @@ type Decimal | |||||
d.to_integer | ||||||
# => 2345 | ||||||
to_integer : Integer | ||||||
to_integer self = | ||||||
to_integer self -> Integer = | ||||||
i = self.big_decimal.toBigInteger | ||||||
if self == i then i else | ||||||
Warning.attach (Loss_Of_Numeric_Precision.Warning self i) i | ||||||
|
@@ -791,8 +801,8 @@ type Decimal | |||||
d = Decimal.new "23.45" | ||||||
d.to_float | ||||||
# => 23.45 | ||||||
to_float : Integer | ||||||
to_float self = | ||||||
to_float : Float | ||||||
to_float self -> Float = | ||||||
f = self.big_decimal.doubleValue | ||||||
if f.is_finite then attach_loss_of_numeric_precision self f else | ||||||
message = "Outside representable Float range (approximately (-1.8E308, 1.8E308))" | ||||||
|
@@ -942,7 +952,7 @@ type Decimal | |||||
@format make_number_format_selector | ||||||
@locale Locale.default_widget | ||||||
format : Text -> Locale -> Text | ||||||
format self format:Text="" locale:Locale=Locale.default = | ||||||
format self format:Text="" locale:Locale=Locale.default -> Text = | ||||||
symbols = DecimalFormatSymbols.new locale.java_locale | ||||||
formatter = DecimalFormat.new format symbols | ||||||
formatter.format self.big_decimal | ||||||
|
@@ -986,50 +996,90 @@ type Decimal | |||||
Decimal.parse "123.456.789,87654" locale=Locale.italy | ||||||
# => 123456789.87654 | ||||||
parse : Text -> Locale | Nothing -> Decimal ! Number_Parse_Error | ||||||
parse text locale:(Locale | Nothing)=Nothing = case locale of | ||||||
Nothing -> Decimal.from_string text | ||||||
parse text locale:(Locale | Nothing)=Nothing -> Decimal ! Number_Parse_Error = case locale of | ||||||
Nothing -> Decimal.from_text text | ||||||
Locale.Value java_locale -> Panic.catch ParseException ((NumberFormat.getInstance java_locale).parse text) _-> | ||||||
Error.throw (Number_Parse_Error.Error text) | ||||||
|
||||||
## PRIVATE | ||||||
precision : Integer | ||||||
precision self = self.big_decimal.precision | ||||||
precision self -> Integer = self.big_decimal.precision | ||||||
|
||||||
## PRIVATE | ||||||
scale : Integer | ||||||
scale self = self.big_decimal.scale | ||||||
scale self -> Integer = self.big_decimal.scale | ||||||
|
||||||
## PRIVATE | ||||||
with_scale : Integer -> Decimal | ||||||
private with_scale self new_scale:Integer = | ||||||
private with_scale self new_scale:Integer -> Decimal = | ||||||
if self.scale == new_scale then self else | ||||||
Decimal.Value (self.big_decimal.setScale new_scale) | ||||||
|
||||||
## PRIVATE | ||||||
unscaled_value : Integer | ||||||
unscaled_value self = self.big_decimal.unscaledValue | ||||||
unscaled_value self -> Integer = self.big_decimal.unscaledValue | ||||||
|
||||||
## PRIVATE | ||||||
internal_representation : [Integer] | ||||||
internal_representation self = [self.unscaled_value, self.precision, self.scale] | ||||||
internal_representation self -> [Integer] = [self.unscaled_value, self.precision, self.scale] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is still valid. Probably accepted by the compiler, but I have no idea what it will do. I think we should use
Suggested change
instead, as that's what is used most of the time. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is what happens when you write in other languages on the weekend. |
||||||
|
||||||
## PRIVATE | ||||||
Note: the underlying Java `BigDecimal` implementation is not affected by | ||||||
locale. | ||||||
to_text : Text | ||||||
to_text self = self.big_decimal.toString | ||||||
to_text self -> Text = self.big_decimal.toString | ||||||
|
||||||
## PRIVATE | ||||||
Note: the underlying Java `BigDecimal` implementation is not affected by | ||||||
locale. | ||||||
to_display_text : Text | ||||||
to_display_text self = self.big_decimal.toString | ||||||
to_display_text self -> Text = self.big_decimal.toString | ||||||
|
||||||
## PRIVATE | ||||||
Note: the underlying Java `BigDecimal` implementation is not affected by | ||||||
locale. | ||||||
to_text_without_scientific_notation : Text | ||||||
to_text_without_scientific_notation self = self.big_decimal.toPlainString | ||||||
to_text_without_scientific_notation self -> Text = self.big_decimal.toPlainString | ||||||
|
||||||
## ICON input_number | ||||||
Construct a `Decimal` from a string, integer or float. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume as @jdunkerley suggested we probably also want to replace string with Text here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||||||
|
||||||
Arguments: | ||||||
- x: The `Text`, `Integer`, or `Float` to construct a `Decimal` from. | ||||||
- mc: The `Math_Context` to use to specify precision and `Rounding_Mode`. | ||||||
If a `Math_Context` is used, there is a possibility of a loss of | ||||||
precision. | ||||||
|
||||||
? Number Format | ||||||
|
||||||
The textual format for a Decimal is defined at | ||||||
https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#BigDecimal-java.lang.String-. | ||||||
|
||||||
! Error Conditions | ||||||
|
||||||
- If the `Text` argument is incorrectly formatted, a `Number_Parse_Error` | ||||||
is thrown. | ||||||
- If the construction of the Decimal results in a loss of precision, a | ||||||
`Loss_Of_Numeric_Precision` warning is attached. This can only happen | ||||||
if a `Math_Context` value is explicitly passed. | ||||||
|
||||||
^ Example | ||||||
Create a `Decimal` from a string. | ||||||
|
||||||
c = dec "12.345" | ||||||
|
||||||
^ Example | ||||||
Create a `Decimal` from an integer. | ||||||
|
||||||
c = dec 12345 | ||||||
|
||||||
^ Example | ||||||
Create a `Decimal` from a float. | ||||||
|
||||||
c = dec 12.345 | ||||||
dec : Text | Integer | Float -> Math_Context | Nothing -> Decimal ! Arithmetic_Error | Number_Parse_Error | ||||||
dec (x : Text | Integer | Float) (mc : Math_Context | Nothing = Nothing) -> Decimal ! Arithmetic_Error | Number_Parse_Error = | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder what we should do with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shall we just add 2 constructors to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
Decimal.new x mc | ||||||
|
||||||
## PRIVATE | ||||||
handle_number_format_exception ~action = | ||||||
|
@@ -1065,7 +1115,7 @@ Comparable.from (_ : Decimal) = Decimal_Comparator | |||||
Comparable.from (_ : Number) = Decimal_Comparator | ||||||
|
||||||
## PRIVATE | ||||||
Decimal.from (that : Text) = Decimal.from_string that | ||||||
Decimal.from (that : Text) = Decimal.from_text that | ||||||
|
||||||
## PRIVATE | ||||||
Decimal.from (that : Integer) = Decimal.new that | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.