Csvhelper: Writing double data to csv results in error

Created on 13 Dec 2019  路  6Comments  路  Source: JoshClose/CsvHelper

Describe the bug
Write a list with double type combined data to a csv file. The original value will be inconsistent with the data written in csv

To Reproduce

  1. my code
    ```c#
    public class test
    {
    public double? a { get; set; }
    public double? b { get; set; }
    }
    test t = new test
    {
    a = 16.3,
    b = 22.5
    };
    List list = new List
    {
    t
    };
    using (var writer = new StreamWriter( @".\test.csv" , false, Encoding.GetEncoding("GB2312")))
    using (var csv = new CsvWriter(writer))
    {
    csv.WriteRecords(list);
    }

```

  1. Get the contents of the csv file
    image

Expected behavior
The content of the csv file I need to get is consistent with the values in my program

Screenshots
image

image

Additional context
VisualStudio 2019
.net framewokr 4.7.2
Microsoft.CSharp 4.5.0

bug

Most helpful comment

I changed it to use R if possible.

defaultFormat = double.TryParse(double.MaxValue.ToString("R"), out _) ? "R" : "G17";

I pushed this to nuget in version 12.2.3.

All 6 comments

According to issue https://github.com/JoshClose/CsvHelper/issues/1409, it's using round-trip format. This can be overridden in configuration.

csv.Configuration.TypeConverterOptionsCache.AddOptions<double?>(new TypeConverterOptions { Formats = new string[] { "" } });

According to issue #1409, it's using round-trip format. This can be overridden in configuration.

csv.Configuration.TypeConverterOptionsCache.AddOptions<double?>(new TypeConverterOptions { Formats = new string[] { "" } });

I don't think this is a good idea. The problem is that the csvhelper class library does not parse the data normally. Instead of manually correcting this error.
I think it should be fixed by csvhelper.

The default number that is written needs to be round-trip-able. Microsoft says to use G17 for Double and G9 for Single as the round-trip format R doesn't always work.

https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#the-round-trip-r-format-specifier

Here is a bug and the reason it doesn't work.

https://stackoverflow.com/questions/24299692/why-is-a-round-trip-conversion-via-a-string-not-safe-for-a-double

I see your point though. 16.3 being written as 16.300000000000001 is silly. The R format doesn't do that.

I'd like to use the R format by default, as that is fixed in current .NET Core implementations. I think there needs to be an easy way for people to configure the G17 and G9 formats without really knowing what it is. Maybe something like a configuration LegacyRoundTripFormat with a description Uses G17 for Double and G9 for Single round trip format instead of R. Use this if a round trip fails. Or maybe the defaults should be set using a pre-processor directive.

I think I'm going to do a test when creating the converter for a Single and Double and setting an appropriate default. If the round-trip works with R it'll use that. If it fails, it'll use the legacy formats.

I changed it to use R if possible.

defaultFormat = double.TryParse(double.MaxValue.ToString("R"), out _) ? "R" : "G17";

I pushed this to nuget in version 12.2.3.

Good Job

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Dushyant262 picture Dushyant262  路  4Comments

mabead picture mabead  路  3Comments

dsotiriades picture dsotiriades  路  3Comments

DmitryEfimenko picture DmitryEfimenko  路  3Comments

JoshClose picture JoshClose  路  4Comments