---
title: "Working with NumericValueAsString — Trading Analytics | Roundly"
description: "The bcmath value object behind every figure — creation, arithmetic and mutability, rounding, comparisons and display formatting."
url: https://roundly-consulting.com/open-source/docs/trading-analytics-for-laravel/numeric-values
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Trading Analytics for Laravel](https://roundly-consulting.com/open-source/docs/trading-analytics-for-laravel.md)

# Working with NumericValueAsString

All numeric results are NumericValueAsString value objects backed by a precise bcmath string. Build one with the ::of() named constructor — cleaner than new:

```php
use RoundlyConsulting\TradingAnalytics\DataTransferObjects\NumericValueAsString;

NumericValueAsString::of('1.005')->round(2)->toRawString();  // '1.01' — half away from zero
NumericValueAsString::of('1.005', scale: 2)->toRawString();  // '1.00' — the scale truncates
NumericValueAsString::of('1e-5')->toRawString();             // '0.0000100000'
NumericValueAsString::of(0.00001)->toRawString();            // '0.0000100000' — floats expand exactly

$value = NumericValueAsString::of('21', scale: 2);
(string) $value->withSuffix('USD');  // '21.00 USD'
$value->toFloat();                   // 21.0, when you explicitly want a float
$value->toInt();                     // 21
```

Input is read exactly: numeric strings (padding allowed), integers, floats and exponent notation ('1.5e-3', 0.00001) are expanded into plain decimals before bcmath sees them.

## Arithmetic and mutability

add(), subtract(), multiply(), divide(), pow() and abs() change the value in place and return it, so they chain. Pass immutable: true to get a new instance instead — do that when you compute with the engine’s results, so the results themselves stay untouched:

```php
$a = NumericValueAsString::of('10.50', scale: 2);

$a->add(1)->subtract('0.5')->multiply(2);  // mutates $a in place and chains
$a->toRawString();                         // '22.00'

$b = $a->divide(4, immutable: true);       // a new instance; $a is unchanged
$b->toRawString();                         // '5.50'

$a->pow(2, immutable: true);               // '484.00' — integer exponents only
NumericValueAsString::of('-3.25', scale: 2)->abs()->toRawString(); // '3.25'
```

round($scale) rounds half away from zero (bcmath itself only truncates) and switches the value to the new scale.

## Comparisons

```php
$v = NumericValueAsString::of('0.75', scale: 4);

$v->isGreaterThan('0.5');       // true
$v->isLessThanOrEqualTo(1);     // true
$v->equals('0.7500');           // true
$v->isZero();                   // false
$v->isPositiveNonZero();        // true
```

isGreaterThanOrEqualTo(), isLessThan() and isNonZero() complete the set. Every comparison accepts a string, int, float or another NumericValueAsString.

## Display formatting

Format a result for display without mutating the stored value using the immutable withPrefix() / withSuffix() helpers, which return a new instance. toString() (and a (string) cast) joins prefix, value and suffix with spaces; toRawString() is always the bare number:

```php
$fees = $analytics->commission->global->total->total;

$fees->withSuffix('USD')->toString();    // '19.00 USD' — a new instance
$fees->withPrefix('Fees:')->toString();  // 'Fees: 19.00'
$fees->toString();                       // '19.00' — the original is unchanged

$fees->toArray();
// ['value' => '19.00', 'scale' => 2, 'prefix' => '', 'suffix' => '', 'formatted' => '19.00']
```

Which figures follow the run’s scale and which have a fixed one is listed under Precision.

## Reference

- of($value, scale: 10, prefix: '', suffix: '') — named constructor; new NumericValueAsString(...) accepts the same named arguments.
- set($value, ?scale) — replace the value; scale() / getScale() — change or read the scale.
- clone() / cloneWithScale($scale) — copies of the value, without prefix or suffix.
- wasChanged() — whether the value was last changed by an arithmetic operation.
- toString(), toRawString(), toInt(), toFloat(), toArray(), toJson().

Dividing by zero throws DivisionByZeroException; non-numeric input ('abc', INF, NAN), an exponent above 1000 or a fractional pow() exponent throws InvalidNumericOperationException; a negative scale throws InvalidScaleException.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/trading-analytics-for-laravel.md)
