Skip to content

Commit

Permalink
Add format parameter to Float.parse (#11229)
Browse files Browse the repository at this point in the history
  • Loading branch information
GregoryTravis authored Oct 7, 2024
1 parent cce50fa commit 47bf591
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
- [Extend the range of `floor`, `ceil`, `trunc` to values outside the `Long`
range.][11135]
- [Added `format` parameter to `Decimal.parse`.][11205]
- [Added `format` parameter to `Float.parse`.][11229]

[10614]: https://github.com/enso-org/enso/pull/10614
[10660]: https://github.com/enso-org/enso/pull/10660
Expand All @@ -89,6 +90,7 @@
[11120]: https://github.com/enso-org/enso/pull/11120
[11135]: https://github.com/enso-org/enso/pull/11135
[11205]: https://github.com/enso-org/enso/pull/11205
[11229]: https://github.com/enso-org/enso/pull/11229

#### Enso Language & Runtime

Expand Down
58 changes: 46 additions & 12 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso
Original file line number Diff line number Diff line change
Expand Up @@ -750,23 +750,57 @@ type Float
GROUP Conversions
ICON convert

Parses a textual representation of a float into a float number, returning
a `Number_Parse_Error` if the text does not represent a valid float.
Parses a string into a `Float`, returning a `Number_Parse_Error` if the
text does not represent a valid `Float`.

Arguments:
- text: The text to parse into a float.
- locale: The locale that specifies the format to use when parsing
- text: The text to parse into a `Float`.
- locale: The locale that specifies the format to use when parsing.
- format: The Java-style format to use to parse the string.

! Error Conditions

- If `text` is incorrectly formatted, a `Number_Parse_Error` is thrown.
- If `format` is incorrectly formatted (or uses digit separators that
differ from the ones specified by the locale), an `Illegal_Argument`
is thrown.

> Example
Parse a `Float` with no locale specifier.

Float.parse "123456789.87654"
# => 123456789.87654

> Example
Parse a `Float` with the default locale.

Float.parse "123,456,789.87654" locale=Locale.default
# => 123456789.87654

> Example
Parse a `Float` with the US locale.

Float.parse "123,456,789.87654" locale=Locale.us
# => 123456789.87654

> Example
Parse a `Float` with the Italy locale.

Float.parse "123.456.789,87654" locale=Locale.italy
# => 123456789.87654
> Example
Parse the text "7.6" into a float number.
Parse a `Float` with an explicit negative number format.

Float.parse "7.6"
parse : Text -> Locale | Nothing -> Float ! Number_Parse_Error
parse text locale=Nothing = case locale of
Nothing -> Panic.catch NumberFormatException (Double.parseDouble text) _->
Error.throw (Number_Parse_Error.Error text)
Locale.Value java_locale -> Panic.catch ParseException ((NumberFormat.getInstance java_locale).parse text) _->
Error.throw (Number_Parse_Error.Error text)
Float.parse "(123,456,789.654)" format="###,###.##;(###,###.##)"
# => -123456789.654
parse : Text -> Locale | Nothing -> Float ! Number_Parse_Error ! Illegal_Argument
parse text locale:Locale=Locale.default format:Text="" -> Float ! Number_Parse_Error ! Illegal_Argument =
Illegal_Argument.handle_java_exception <|
# `getInstance` returns `DecimalFormat` or a subclass of `DecimalFormat`.
decimal_format = NumberFormat.getInstance locale.java_locale
decimal_format.applyLocalizedPattern format
Panic.catch ParseException (decimal_format.parse text) _->
Error.throw (Number_Parse_Error.Error text)

## ICON input_number

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1536,7 +1536,7 @@ Text.last_index_of self term="" start=-1 case_sensitivity=Case_Sensitivity.Sensi
"7.6".parse_float
@locale Locale.default_widget
Text.parse_float : Locale | Nothing -> Float ! Number_Parse_Error
Text.parse_float self locale=Nothing = Float.parse self locale
Text.parse_float self locale=Locale.default = Float.parse self locale

## ALIAS integer from text, to_integer
GROUP Conversions
Expand Down
22 changes: 22 additions & 0 deletions test/Base_Tests/src/Data/Numbers_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,28 @@ add_specs suite_builder =
Float.parse "000000,0001" l . should_equal 0.0001
Float.parse "aaaa" l . should_fail_with Number_Parse_Error

group_builder.specify "should parse correctly with format and/or locale" <|
Float.parse "123,456,789.87654" . should_equal 123456789.87654
Float.parse "123.456.789,87654" locale=Locale.italy . should_equal 123456789.87654

Float.parse "123,456,789.88" format="#,###.##" . should_equal 123456789.88
Float.parse "123.456.789,88" format="#.###,##" locale=Locale.italy . should_equal 123456789.88
Float.parse "1,23,45,67,89.88" format="#,##.##" . should_equal 123456789.88
Float.parse "1.23.45.67.89,88" format="#.##,##" locale=Locale.italy . should_equal 123456789.88

Float.parse "123.456.789,88" format="#,###.##" locale=Locale.italy . should_fail_with Illegal_Argument
Float.parse "123,456,789.88" format="#.###,##" . should_fail_with Illegal_Argument

Float.parse "123,456,789.87654" locale=Locale.italy . should_equal 123.456
Float.parse "123.456.789,87654" locale=Locale.us . should_equal 123.456

Float.parse "123,456,789.654" format="###,###.##;-###,###.##" . should_equal 123456789.654
Float.parse "-123,456,789.654" format="###,###.##;-###,###.##" . should_equal -123456789.654
Float.parse "(123,456,789.654)" format="###,###.##;-###,###.##" . should_fail_with Number_Parse_Error
Float.parse "123,456,789.654" format="###,###.##;(###,###.##)" . should_equal 123456789.654
Float.parse "-123,456,789.654" format="###,###.##;(###,###.##)" . should_fail_with Number_Parse_Error
Float.parse "(123,456,789.654)" format="###,###.##;(###,###.##)" . should_equal -123456789.654

group_builder.specify "Float should parse hundred factorial well" <|
txt = hundred_factorial.to_text + ".345"
float = Float.parse txt
Expand Down

0 comments on commit 47bf591

Please sign in to comment.