Skip to content
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

Slightly incorrect serialized double values #637

Closed
Androkai opened this issue Sep 29, 2021 · 3 comments · Fixed by #695
Closed

Slightly incorrect serialized double values #637

Androkai opened this issue Sep 29, 2021 · 3 comments · Fixed by #695

Comments

@Androkai
Copy link

Describe the bug

When serializing many double values with 2 decimal places each, I observe reproducible deviations for some fixed values, as if an unfortunate type conversion is taking place somewhere.
For example, 26.67 always becomes 26.0000002

Since I need values with exactly 2 decimal places in a subsequent processing step, I ask for help with this problem.

To Reproduce

using System;
using YamlDotNet.Serialization;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            var serializer = new SerializerBuilder().Build();

            double price = 26.67;

            // output value to console (correct)
            Console.WriteLine(price);

            // serialize value and output to console (incorrect)
            serializer.Serialize(Console.Out, price);
        }
    }
}

The output will be:

26.67
26.670000000000002

Tested with YamlDotNet 11.2.1 in a .NET 5.0.9 console application.

@CxRP
Copy link

CxRP commented Oct 25, 2021

I have the same issue using .NET 4.7.1 and YamlDotNet 11.2.1 when Serialize from ExpandoObject (converted from JSON)

9.4 --> 9.4000000000000004

// convert object to JSON
var json = JsonConvert.SerializeObject(this.NewConfig, settings);
var expConverter = new ExpandoObjectConverter();
dynamic deserializedObject = JsonConvert.DeserializeObject<ExpandoObject>(json, expConverter);

// convert JSON to YAML
ISerializer serializer = new SerializerBuilder()
  .WithNamingConvention(HyphenatedNamingConvention.Instance)
  .Build();
var yaml = serializer.Serialize(deserializedObject);

@CodeVicious
Copy link

CodeVicious commented Feb 23, 2022

Same issue here,
.Net (core) 5.0 and YamlDontNet 11.2.1

Is there a workaround?

@Androkai
Copy link
Author

Since the serialized values seem to be very close to the initial value, and in my case it is not critical if an error of +/- 0.01 occurs, I currently just trim them with a lookbehind regex:

/// <summary>
/// Since YamlDotNet's double serialization is buggy, we'll
/// fix it by using this hack to cut decimal places after the
/// second one.<br></br>Check the issue on Github:
/// <see href="https://github.com/aaubry/YamlDotNet/issues/637"/>
/// </summary>
/// <param name="yaml">The serialized YAML text</param>
/// <returns>
/// The input text with all "price: 12.3456789..." occurrences
/// truncated to a maximum of two decimal places.
/// </returns>
private string TruncatePriceDecimals(string yaml)
{
    return Regex.Replace(yaml, "(?<=price: -?[0-9]+\\.[0-9][0-9])[0-9]+", string.Empty);
}

However, for most applications this should be critical and needs a real fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants