Skip to content
Merged
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
18 changes: 17 additions & 1 deletion Docs/precision.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,23 @@ Units.NET was not designed for high-precision, but rather a tool of convenience
- Centimeter => Meter => Kilometer
- As a result, most conversions have a rounding error. The error is larger for units that are way larger or way smaller than the base unit.
- A rounding error of `1e-5` is accepted for round-trip conversion of most units in the library. In many use cases this is sufficient, but for others this may not be acceptable.
- There is support for [custom conversion functions](https://github.com/angularsen/UnitsNet#convert-between-units-of-custom-quantity) between unit A to unit B, typically to add 3rd party units. This can also be used to improve the precision for specific conversions since it no longer converts via the base unit.
- In v6, unit conversion definitions can be customized before the converter is built. This can be used to override a built-in conversion factor or add conversion functions for custom quantities.

## Overriding built-in unit conversions

Built-in unit definitions can be customized through `UnitsNetSetup.ConfigureDefaults()` before the default setup is used:

```csharp
UnitsNetSetup.ConfigureDefaults(builder => builder.ConfigureQuantity(() =>
Pressure.PressureInfo.CreateDefault(units =>
units.Configure(PressureUnit.InchOfWaterColumn, unit =>
unit.WithConversionFactorFromBase(999)))));

var pressure = Pressure.FromPascals(1);
double value = pressure.As(PressureUnit.InchOfWaterColumn); // 999
```

For isolated conversions, create a custom `QuantityInfo` and pass it to a custom `UnitConverter` instead of changing the global defaults. See `Samples/UnitsNetSetup.Configuration/ConfigureWithCustomConversions.cs` for a complete example.

## Test precision

Expand Down
36 changes: 36 additions & 0 deletions UnitsNet.Tests/UnitConverterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,42 @@ public void TryGetConversionFunction_WithCustomUnitConversion_ReturnsTrue(bool f
Assert.Equal(1800, conversionFunction!(18));
});
}

[Theory]
[MemberData(nameof(ConverterTestOptions))]
public void ConvertValue_WithCustomBuiltInUnitDefinition_UsesConfiguredConversion(bool freeze, ConversionCachingMode cachingMode, bool reduceConstants)
{
var customPressureInfo = Pressure.PressureInfo.CreateDefault(unitDefinitions =>
unitDefinitions.Configure(PressureUnit.InchOfWaterColumn, definition => definition.WithConversionFactorFromBase(999)));

var unitParser = new UnitParser([customPressureInfo]);
var convertOptions = new QuantityConverterBuildOptions(freeze, cachingMode, reduceConstants);
var unitConverter = UnitConverter.Create(unitParser, convertOptions);

var pressure = Pressure.FromPascals(1);

Assert.Multiple(() =>
{
QuantityValue convertedValue = unitConverter.ConvertValue(1, PressureUnit.Pascal, PressureUnit.InchOfWaterColumn);

Assert.Equal(999, convertedValue);
}, () =>
{
QuantityValue convertedValue = unitConverter.ConvertValue(999, PressureUnit.InchOfWaterColumn, PressureUnit.Pascal);

Assert.Equal(1, convertedValue);
}, () =>
{
QuantityValue convertedValue = pressure.As(PressureUnit.InchOfWaterColumn, unitConverter);

Assert.Equal(999, convertedValue);
}, () =>
{
var convertedQuantity = pressure.ToUnit(PressureUnit.InchOfWaterColumn, unitConverter);

Assert.Equal(999, convertedQuantity.Value);
});
}


[Theory]
Expand Down
Loading