Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .php-cs-fixer.cache
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"php":"8.5.1","version":"3.92.3","indent":" ","lineEnding":"\n","rules":{"blank_line_after_namespace":true,"braces_position":true,"class_definition":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":{"closure_fn_spacing":"one"},"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline","keep_multiple_spaces_after_comma":true},"modifier_keywords":{"elements":["method","property"]},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_import_per_statement":true,"single_line_after_imports":true,"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","do","else","elseif","final","for","foreach","function","if","interface","namespace","private","protected","public","static","switch","trait","try","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"array_syntax":{"syntax":"short"},"ordered_imports":{"sort_algorithm":"alpha"},"no_unused_imports":true,"not_operator_with_successor_space":true,"trailing_comma_in_multiline":true,"phpdoc_scalar":true,"unary_operator_spaces":true,"binary_operator_spaces":true,"blank_line_before_statement":{"statements":["break","continue","declare","return","throw","try"]},"phpdoc_single_line_var_spacing":true,"phpdoc_var_without_name":true},"ruleCustomisationPolicyVersion":"null-policy","hashes":{"src\/Number.php":"24aa9f086b4d1f1dca036b52579161aa","src\/Formatter\/Formatter.php":"9964fe6d64137d383a5e82f8ea2da3f8","src\/AbstractNumber.php":"c24a93edb0f978e095dfb5f9b95aa6a6","src\/Exception\/InvalidRoundingModeException.php":"d71e665e4e240b22fdb9db64069e763d","src\/Exception\/DecimalExponentError.php":"ac4b9e400f191ce060ba161da6fb05fc","src\/Exception\/InvalidNumberInputTypeException.php":"5a4835631a06a4c2b21662b11272d2af","src\/Exception\/DivisionByZeroError.php":"3fde70a49d1d654451d3416b120f0589","tests\/NumberTest.php":"63f06c0b0bb535cd8e759891d05fb270","tests\/AbstractNumberImplementationTest.php":"4acfadd14746301afbba928ca3c5ac48","tests\/TestClasses\/Money.php":"d0cfe302a13cebba31984b8349c2ee41"}}
{"php":"8.5.9","version":"3.95.18","indent":" ","lineEnding":"\n","rules":{"blank_line_after_namespace":true,"braces_position":{"allow_single_line_anonymous_functions":false},"class_definition":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":{"closure_fn_spacing":"one"},"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline","keep_multiple_spaces_after_comma":true},"modifier_keywords":{"elements":["method","property"]},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_import_per_statement":true,"single_line_after_imports":true,"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","do","else","elseif","final","for","foreach","function","if","interface","namespace","private","protected","public","static","switch","trait","try","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"array_syntax":{"syntax":"short"},"ordered_imports":{"sort_algorithm":"alpha"},"no_unused_imports":true,"not_operator_with_successor_space":true,"trailing_comma_in_multiline":true,"phpdoc_scalar":true,"unary_operator_spaces":true,"binary_operator_spaces":true,"blank_line_before_statement":{"statements":["break","continue","declare","return","throw","try"]},"phpdoc_single_line_var_spacing":true,"phpdoc_var_without_name":true},"ruleCustomisationPolicyVersion":"null-policy","hashes":{"tests\/MemoryTest.php":"f451fe647e1c46a5e6c40408d2058c08","tests\/FormatterTest.php":"9f21b1f3598eb7bcace79f1f9638c9d9","src\/Formatter\/Formatter.php":"02e641ed81c4fc9d473bce532d111fcc","src\/Exception\/InvalidRoundingModeException.php":"d71e665e4e240b22fdb9db64069e763d","src\/Exception\/InvalidNumberInputTypeException.php":"5a4835631a06a4c2b21662b11272d2af","src\/Exception\/DivisionByZeroError.php":"3fde70a49d1d654451d3416b120f0589","src\/Exception\/DecimalExponentError.php":"ac4b9e400f191ce060ba161da6fb05fc","src\/Number.php":"24aa9f086b4d1f1dca036b52579161aa","src\/AbstractNumber.php":"b7eb4020a52cbd8a7b9627f9d8080cee","tests\/TestClasses\/Money.php":"d0cfe302a13cebba31984b8349c2ee41","tests\/AbstractNumberImplementationTest.php":"4acfadd14746301afbba928ca3c5ac48","tests\/NumberTest.php":"08497bda919dd42123490531c37988ab"}}
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,31 @@ $number->ceil();
$number->floor();
```

Rounding is done with BC Math, so numbers that do not fit a float are rounded exactly as well:

``` php
$number = new Number('123456789012345678901234567890.55');

// '123456789012345678901234567890.6'
$number->round(1)->toString(1);
```

A precision and one of four rounding modes can be given. Halves are rounded away from zero by default:

``` php
// '5.0000', halves are rounded away from zero
Number::create('4.5')->round(0, Number::ROUND_HALF_UP);

// '4.0000', halves are rounded towards zero
Number::create('4.5')->round(0, Number::ROUND_HALF_DOWN);

// '4.0000', halves are rounded to the nearest even number
Number::create('4.5')->round(0, Number::ROUND_HALF_EVEN);

// '5.0000', halves are rounded to the nearest odd number
Number::create('4.5')->round(0, Number::ROUND_HALF_ODD);
```

### Immutable & Chaining
Since the `Number` class is immutable, most methods will return a new `Number` instance.

Expand All @@ -263,6 +288,26 @@ $result = $number
->toString();
```

Every instance knows the instance it was derived from, which lets you trace a calculation back:

``` php
$five = new Number(5);
$seven = $five->add(2);

// '5.0000'
$seven->parent()->toString();
```

The parent is referenced weakly, so intermediate results of a chain are not kept in memory. Whenever the parent
has been garbage collected, `parent()` returns `null`. Keep a reference to the numbers you want to trace back to:

``` php
$result = (new Number(5))->add(2)->add(8);

// null, the result of add(2) was not referenced by anything else
$result->parent();
```

## Extensibility
We encourage you to create custom implementations of the `AbstractNumber` class for your specific use cases. This enables
you to type hint much better which type of number you expect and how they should be formatted.
Expand Down
Loading
Loading