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

Real value parsing from ASCII representation. #1750

Closed
sethhall opened this issue May 30, 2024 · 3 comments
Closed

Real value parsing from ASCII representation. #1750

sethhall opened this issue May 30, 2024 · 3 comments
Assignees
Labels
Enhancement Improvement of existing functionality

Comments

@sethhall
Copy link
Member

In the tests (https://github.com/zeek/spicy/blob/main/tests/spicy/types/real/parse.spicy) it appears that there is only support for parsing reals that are stored as IEEE values. It would be nice to be able to parse string representations of floating point numbers into real values.

Like if the actual ascii bytes "-1.34432" were parsed from a byte stream. It doesn't seem like this is currently possible with built in mechanisms.

@bbannier bbannier added the Enhancement Improvement of existing functionality label May 30, 2024
@bbannier
Copy link
Member

Thanks for the issue, this seems indeed currently missing. Another good place for this would probably be as a method on bytes where we already provide functions like to_int, to_uint or to_time. Such a function would be locale-dependent and not loss-free since not all decimal numbers can be represented exactly as real, so it would be more "dangerous" than the exiting functions.

For the time being one could implement conversion bytes -> real in a helper function, e.g.,

function to_real(str: bytes): real {
    # Assume locale with decimal separator `.`.
    local xs = str.split(b".");

    # A valid fractional number has the form `XXX.YYYYY` with exactly one separator.
    assert |xs| == 2;

    local a = cast<real>(xs[0].to_int());

    local b = xs[1];
    local sgn = a > 0 ? 1.0 : -1.0;

    return a + sgn * cast<real>(b.to_uint()) / (10**cast<real>(|b|));
}

type X = unit {
    x: bytes &until=b"\n" &convert=to_real($$);
};

@sethhall
Copy link
Member Author

Oh nice! I couldn't figure out how to write that function. Thanks!

@sethhall
Copy link
Member Author

sethhall commented Jun 1, 2024

Thanks again for that function. Here's a mostly complete json parser I needed it for... https://gist.github.com/sethhall/386c941a0f778d8b79be03c7fbfd47d0

@rsmmr rsmmr self-assigned this Jun 6, 2024
rsmmr added a commit that referenced this issue Jun 6, 2024
This interprets the data as representing an ASCII-encoded floating
point number and converts that into a ``real``. The data can be in
either decimal or hexadecimal format. If it cannot be parsed as
either, throws an `InvalidValue` exception.

Closes #1750.
rsmmr added a commit that referenced this issue Jun 7, 2024
This interprets the data as representing an ASCII-encoded floating
point number and converts that into a ``real``. The data can be in
either decimal or hexadecimal format. If it cannot be parsed as
either, throws an `InvalidValue` exception.

Closes #1750.
rsmmr added a commit that referenced this issue Jun 12, 2024
This interprets the data as representing an ASCII-encoded floating
point number and converts that into a ``real``. The data can be in
either decimal or hexadecimal format. If it cannot be parsed as
either, throws an `InvalidValue` exception.

Closes #1750.
rsmmr added a commit that referenced this issue Jun 12, 2024
This interprets the data as representing an ASCII-encoded floating
point number and converts that into a ``real``. The data can be in
either decimal or hexadecimal format. If it cannot be parsed as
either, throws an `InvalidValue` exception.

Closes #1750.
@rsmmr rsmmr closed this as completed in 26431ff Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement Improvement of existing functionality
Projects
None yet
Development

No branches or pull requests

3 participants