certik / yaml-cpp

Automatically exported from code.google.com/p/yaml-cpp
MIT License
0 stars 0 forks source link

Saving Decimal Numbers as Integers #226

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Save 1.0f to a YAML::Node and the file will only show 1, which when loaded will 
yield an integer if you test if .as<int> doesn't throw an exception before 
trying to convert it to a float.

It should output 1.0 to the file instead.

Original issue reported on code.google.com by ARandomFurry on 16 Nov 2013 at 10:11

GoogleCodeExporter commented 9 years ago
I have an uneasy relationship with the int/float aliasing. I'd rather not 
special case this unless there's a good reason. Do you have an example where 
you really need to check if it's an integer, and otherwise, a float?

Original comment by jbe...@gmail.com on 16 Nov 2013 at 5:29

GoogleCodeExporter commented 9 years ago
The data structure I'm reading from YAML has a value at key "Data". This value 
can be either an integer, float, or string.

Original comment by ARandomFurry on 17 Nov 2013 at 10:24

GoogleCodeExporter commented 9 years ago
You could tag the node with its type?

(You still haven't quite answered the question - why do you need to distinguish 
an int from a float? If you plain just *want* it, then tag it; if you have a 
good reason that might generalize to other users, I'll consider adding it to 
the library.)

Original comment by jbe...@gmail.com on 18 Nov 2013 at 5:55

GoogleCodeExporter commented 9 years ago
I could store another value to denote the data's type, but that is more error 
prone and inflates the data file (which can contain thousands of these 
structures). The reason for wanting this is because of polymorphism, and if I 
incorrectly create a data structure as an integer when it should be a float 
then when converting it all back to binary data it will crash the program 
because of the wrong data type.

Original comment by ARandomFurry on 18 Nov 2013 at 10:40

GoogleCodeExporter commented 9 years ago
What about string/int? What if your string could also be read as an int? Or a 
float?

Also, I'm not sure I follow about the binary data thing - if you're storing it 
as binary data, why don't you just use a binary file format? (i.e., and not 
YAML?) Again - what problem are you trying to solve?

Original comment by jbe...@gmail.com on 18 Nov 2013 at 2:09

GoogleCodeExporter commented 9 years ago
I have a binary data format that contains an integer saying what the next piece 
of data is. This data can be an integer, a float, or a string. I want to 
convert this data to a human readable form (Yaml, because it's awesome).

Converting it to Yaml is perfectly fine. However, (and now that you mention 
that strings don't always have quotes) some data is saved in a way that it can 
be read from the Yaml file incorrectly. This doesn't cause any issues except 
when you don't know what type it should be.

If I read a string as number, or a float as an integer, then when converting 
back to the binary format the polymorphic functions I've created would save the 
incorrect integer denoting type, and then the incorrect data. This would make 
use differences in value for a integer read as a float, which can cause a 
crash. Reading a number where a string would be would outright crash.

So, why can't strings always be saved with enclosing quotes, or float always 
with a decimal? Mayhaps create some sort of flag to set on a Node (whilst on 
that topic, still need a flag for flow style)?

Original comment by ARandomFurry on 19 Nov 2013 at 2:33

GoogleCodeExporter commented 9 years ago
Yeah, there definitely is a need for tagging a node so that it emits in a 
certain style (Issue 184), and I'll think about this int/float business too. 
I'm not yet convinced, though, because (a) I still don't understand your use 
case, and (b) there's a cost to *every* parsing/emitting to figure out if, 
e.g., 1 is an int or a float.

Original comment by jbe...@gmail.com on 19 Nov 2013 at 4:48

GoogleCodeExporter commented 9 years ago
The change I'm asking for simply wraps quotes around a string, or adds a 
decimal to a non-integer if it doesn't already have one. The cost of checking 
what data I'm parsing is the try catch blocks.

shared_ptr<Mod> Mod::Load(const YAML::Node& node){
    const YAML::Node& Data=node["Data"];
    string ModIdStr=node["ModId"].as<string>();
    ObjectId ModId;
    for(unsigned int I=0u;I<4u;I++)ModId.Bytes[I]=ModIdStr[I];
    if(Data){
        try{
            float Value=Data.as<float>();
            return shared_ptr<Mod>(new Mod_Float(ModId,Value));
        }catch(...){
            try{
                int Value=Data.as<int>();
                return shared_ptr<Mod>(new Mod_Int(ModId,Value));
            }catch(...){
                try{
                    string Value=Data.as<string>();
                    return shared_ptr<Mod>(new Mod_String(ModId,Value));
                }catch(...){}
            }
        }
    }
    return nullptr;
}

Forgot I had this code.

Original comment by ARandomFurry on 20 Nov 2013 at 1:01

GoogleCodeExporter commented 9 years ago
Wait - do you want to wrap quotes around *every* string? That's a cost to 
readability that we can't do. If not, then you want to yaml-cpp to parse the 
string and see if it could be read as an int or a float (or double, or bool, 
...) and then put quotes around it if it's ambiguous.

(As a side note: I suggest not doing catch (...), but rather catching 
explicitly what you expect.)

Original comment by jbe...@gmail.com on 20 Nov 2013 at 4:13

GoogleCodeExporter commented 9 years ago
The ... was because I didn't care what I caught, I will fix that. Why not add 
the whole flag thing to nodes for output styles (Flow style, explicit quotes, 
explicit decimals).

Original comment by ARandomFurry on 20 Nov 2013 at 2:44

GoogleCodeExporter commented 9 years ago
I'll consider it. If anyone else stars this issue, I'll take that into 
consideration too :)

Original comment by jbe...@gmail.com on 21 Nov 2013 at 3:45