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

unsigned 64bit values output as signed #151

Closed
mbunkus opened this issue Nov 22, 2015 · 7 comments
Closed

unsigned 64bit values output as signed #151

mbunkus opened this issue Nov 22, 2015 · 7 comments

Comments

@mbunkus
Copy link

mbunkus commented Nov 22, 2015

I'm trying to add JSON output to mkvmerge's identification output. mkvmerge is a tool dealing with Matroska media files, and those in turn use a lot of unsigned 64bit values – e.g. each track in that file has a unique ID that's basically a random 64bit number.

Outputting those results in signed 64bit values being output instead, obviously.

Trivial test case:

std::cout << nlohmann::json{std::numeric_limits<uint64_t>::max()};

Output:

[-1]

When parsing JSON with such huge values: it would be nice to be able to query the JSON object if the encoded value was in fact negative, but for my use case encoding is the important part, not parsing.

This is obviously similar to #30, but probably harder to fix. Maybe you'll have to store integers both signed and unsigned and output them depending on which type has been used…

BTW: I really love using your library. Thanks for providing it.

@nlohmann
Copy link
Owner

I'm on holiday right now.
I'll check when I'm back in two weeks.

@mbunkus
Copy link
Author

mbunkus commented Nov 23, 2015

No worries, it's not urgent. Enjoy your vacation.

@nlohmann
Copy link
Owner

nlohmann commented Dec 6, 2015

Hi @mbunkus, could the following fix of setting the type of integers using template arguments for basic_json help:

#include <json.hpp>

using ujson = nlohmann::basic_json<std::map, std::vector, std::string, bool, uint64_t, double>;

int main() {
    std::cout << ujson{std::numeric_limits<uint64_t>::max()} << "\n";
}

On my machine, the output is [18446744073709551615].

@mbunkus
Copy link
Author

mbunkus commented Dec 6, 2015

I'm currently doing something similar (I've simply replaced int64_t with uint64_t in my copy). This works for me in this particular instance as I only need non-negative integers.

In general this is not a solution, though. I cannot mix json and ujson either; if I try to use an instance of ujson with a json object or array an exception is thrown when dumping them to a JSON string.

@nlohmann
Copy link
Owner

nlohmann commented Dec 6, 2015

Any idea how to fix this? 128 bit integers seem to introduce a boost dependency (or any other third-party code).

@mbunkus
Copy link
Author

mbunkus commented Dec 6, 2015

One possible solution might be to have both a signed and an unsigned integer type stored. Upon parsing check if the value is negative; then use the signed type; if it's positive and > std::numeric_limits<signed-type>::max() then use the unsigned type; otherwise use the signed one. Upon creation store the value either in the signed or the unsigned integer depending on the argument's type, remember that choice and use that knowledge when converting to JSON.

Not a nice solution by any stretch of the imagination, but at least it doesn't introduce external dependencies.

Support for bigger integers would be interesting, but that's a whole other conversation. I'd be perfectly happy to have a working solution for the full range of 64bit signed & unsigned values within the same basic_json type.

@nlohmann
Copy link
Owner

This change would result in a even more complicated storage of numbers. At this point, I am not planning to implement this. Sorry for the inconvenience.

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

No branches or pull requests

2 participants