Stream: beginners

Topic: Is Infinity or NaN


view this post on Zulip Luke Boswell (Apr 19 2023 at 22:15):

Should we have a function to check if a float (frac?) is positive or negative infinity i.e. Num.isInfinite : Frac range -> Bool? and while I'm at it Num.isNaN : Frac range -> Bool?

» (1 / 0)

inf : Float *             # val1

» (-1 / 0)

-inf : Float *            # val2

view this post on Zulip Richard Feldman (Apr 19 2023 at 22:27):

I think so yeah!

view this post on Zulip Richard Feldman (Apr 19 2023 at 22:27):

(should be Frac, not Float - I think the repl needs to be updated)

view this post on Zulip Ajai Nelson (Apr 20 2023 at 02:57):

That reminds me: for floats, should we have a builtin for distinguishing -0.0 and +0.0? It’s probably not a very common use case, and it seems like a lot of languages don’t have it.

Rust has a few methods that can do this:

(-0.0).is_sign_negative() == true
(+0.0).is_sign_negative() == false

(-0.0).is_sign_positive() == false
(+0.0).is_sign_positive() == true

(-0.0).signum() == -1.0
(+0.0).signum() == +1.0

C has signbit(), which returns -1 for -0.0 and +1 for +0.0.

It should be possible to tell the difference yourself by checking whether you get positive or negative infinity when dividing by it:

isNegativeZero = \n -> n == 0.0 && 1.0 / n < 0

view this post on Zulip Richard Feldman (Apr 20 2023 at 12:02):

I'd say no by default...if there's specific demand for it later, we can revisit

view this post on Zulip Basile Henry (May 02 2023 at 19:31):

I am working on the gen_dev backend implementation for this, and I'm struggling to find examples in the code for casting a float to an int.
I have some idea of what the instructions should look like (https://godbolt.org/z/se8EsTGhr), is this the first time this is needed and I need to build the abstraction for it?

view this post on Zulip Folkert de Vries (May 02 2023 at 19:45):

we should have function to move a float to the stack , and then to read that memory as an integer from the stack

view this post on Zulip Folkert de Vries (May 02 2023 at 19:45):

stack_offset_and_size is probably the magic function

view this post on Zulip Richard Feldman (May 02 2023 at 19:50):

hm, I think we'd need more than that, right?

view this post on Zulip Richard Feldman (May 02 2023 at 19:51):

like if you have 8 bytes organized as an F64, the integer portion of those bytes will not be laid out the same way as (for example) an I64 would be laid out

view this post on Zulip Brendan Hansknecht (May 02 2023 at 19:58):

Yeah, we will need the proper functions that do conversion if we don't have them (don't recall at this point).

view this post on Zulip Brendan Hansknecht (May 02 2023 at 19:59):

So not just data movement but also type conversion

view this post on Zulip Brendan Hansknecht (May 02 2023 at 20:01):

Looks like we have to_float, but I don't see the reverse yet

view this post on Zulip Basile Henry (May 02 2023 at 20:04):

Yeah I think I need to use movss and movsd (for x86) to properly move the bytes between float and int. That first godbolt example used the stack to do that, but maybe we can do it without?

view this post on Zulip Brendan Hansknecht (May 02 2023 at 20:04):

Wait, are you trying to get the exact bytes moved or convert to an int?

view this post on Zulip Basile Henry (May 02 2023 at 20:05):

Looking at to_float I don't think I want to convert like it is done there. I need the raw bits in order to bitwise AND it with a constant

view this post on Zulip Brendan Hansknecht (May 02 2023 at 20:05):

Oh, then i think we have all the move instructions you might need for that

view this post on Zulip Brendan Hansknecht (May 02 2023 at 20:07):

...hmmm...actually not quite. We have enough that you can do it if you dump it to the stack and then load it. We don't have the direct movement between general and float regs

view this post on Zulip Basile Henry (May 02 2023 at 20:08):

I couldn't find the right one, but maybe I just missed it? There are a few to move between stack and freg, but it should be possible to skip the stack I think.
Here is a more full-fledged set of instructions I'm looking to generate: https://godbolt.org/z/cf4znYE68

view this post on Zulip Brendan Hansknecht (May 02 2023 at 20:08):

Would be mov_reg64_freg64. You can add it if you want.

view this post on Zulip Brendan Hansknecht (May 02 2023 at 20:08):

Would be the best answer here

view this post on Zulip Brendan Hansknecht (May 02 2023 at 20:08):

We just haven't added it yet

view this post on Zulip Basile Henry (May 02 2023 at 20:09):

Alright, I'll try to add it! :sweat_smile:

view this post on Zulip Folkert de Vries (May 02 2023 at 20:09):

I just added a movss/movsd from a pointer into a float register

view this post on Zulip Folkert de Vries (May 02 2023 at 20:09):

as in, it's on a branch that I'm working on right now

view this post on Zulip Folkert de Vries (May 02 2023 at 20:10):

because we did not implement that correctly, and LIst.get on a list of floats would just use the last float that the program stored in that register

view this post on Zulip Folkert de Vries (May 02 2023 at 20:10):

it did not look at the pointer at all, even

view this post on Zulip Basile Henry (May 02 2023 at 20:11):

Oh nice! And it need to be a pointer? I don't fully understand how to control the storage associated with a symbol just yet. I have implemented isNaN already, but I have just been assuming they're already in a register. It seems to work

view this post on Zulip Basile Henry (May 02 2023 at 20:12):

Oh, and what's your workflow to test aarch64 when you're running x86? Do we have guides on how to run the test suites in qemu?

view this post on Zulip Folkert de Vries (May 02 2023 at 20:14):

I suspect you actually want the movd instruction from that example?

view this post on Zulip Folkert de Vries (May 02 2023 at 20:14):

that would be a more direct solution, anyway

view this post on Zulip Folkert de Vries (May 02 2023 at 20:15):

I mostly ignore aarch for the time being, my work is usually on a slightly higher level. when the dev backend is fully functional on x86 linux we can (hopefully) quickly fill in the final translation to assembly

view this post on Zulip Brendan Hansknecht (May 02 2023 at 20:18):

I have just been assuming they're already in a register

You probably start by calling something like load_to_general_reg or load_to_float_reg. That deals with the storage for you.

view this post on Zulip Basile Henry (May 02 2023 at 20:21):

Oh yes I did do that :sweat_smile:

view this post on Zulip Basile Henry (May 02 2023 at 20:22):

Folkert de Vries said:

I suspect you actually want the movd instruction from that example?

So I should add an abstraction for it in ASM? I don't think we generate movd movq at the moment

view this post on Zulip Folkert de Vries (May 02 2023 at 20:28):

yes that needs some custom "putting the bytes in the right order"


Last updated: Jul 06 2025 at 12:14 UTC