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

Design questions + discussion #7

Open
tiehuis opened this issue Jun 11, 2017 · 3 comments
Open

Design questions + discussion #7

tiehuis opened this issue Jun 11, 2017 · 3 comments

Comments

@tiehuis
Copy link
Owner

tiehuis commented Jun 11, 2017

Some notes regarding the current implementation, future changes and how we want to conform to libc or not in certain areas.

Rounding Modes

The rounding mode can be set or retrieved and changes how fpu rounds results. Right now I don't really see a compelling reason to bother with this just for the moment since this is architecture specific. The default should suffice.

FLT_EVAL_METHOD

The FLT_EVAL_METHOD macro is a compile-time constant which specifies at what precision intermediate results should be calculated using. The current code just assumes a FLT_EVAL_METHOD of 0 which corresponds to intermediate calculations using the type of the input argument. This should be okay for the moment, since it is simpler and the algorithms should be sufficiently precise regardless of the eval method used.

long double type.

The c_longdouble type is not implemented at all. The rationale is if required, the user should use the libc math library, which makes some sense given it is a c abi type anyway. The long double functions as well generally are more complex to implement as well.

Floating Point Exceptions

There are five exceptions that should be considered. See here for an overview.
These are queried from the fpu and must be implemented for each architecture. We should propagate the correct exceptions where needed, however I'm not too concerned with providing an exception testing interface at least right now.

One important thing though is reviewing all the places where exceptions are generated. Many of these could be improved, and if possible, some generic functions which generate the specific exceptions required would be make the edge cases much easier to understand in the code.

Builtin nan and inf implementations.

Self-explanatory, but these would be useful primarily so they could be used in places which require a constant. The current code uses functions to generate them from a unsigned integer and are non constants. Might be other reasons for it, but I'd be pretty certain that llvm exposes some details for this anyway.

Removing "out" value interfaces

For example, modf has the function signature fn modf32(x: f32, intpart: &f32) -> f32. This could be cleaned up with tuple return type values. See here however for some discussion about this type of feature.

For the moment, we can stick with the "out" and maybe provide a struct return value if desired or wait until some proposal that satisfies this requirement is present.

@andrewrk
Copy link

Rounding Modes
FLT_EVAL_METHOD
Floating Point Exceptions

I agree with what you said.

Builtin nan and inf implementations.

I think we can have nan and inf constants, all we need is the @bitCast builtin function, and make it work at compile time to convert between, e.g. u32 and f32.

Removing "out" value interfaces

Let's experiment with using a struct for the return type in these cases, like this:

const modf32_result = struct {
    fpart: f32,
    intpart: f32,
};
fn modf32(x: f32) -> modf32_result {
     ...
}

A little verbose, but actually not bad at the callsite:

const result = modf32(foo);
// do whatever with result.fpart and result.intpart

Overall this implementation is high quality and I think it's ready to merge into zig standard library if you're ready for that.

@tiehuis
Copy link
Owner Author

tiehuis commented Jun 12, 2017

Sounds good.

I'll change the return type interface and go through and clean up the fpu exception propagation code to be slightly more clear (and correct) just before merging. Once that is complete though it should be ok to do.

tiehuis added a commit that referenced this issue Jun 12, 2017
@andrewrk
Copy link

For force float eval, we do have the ability to write to volatile variables.

var x: f32 = undefined
const ptr = @ptrCast(&volatile f32, &x);
*ptr = foo;

Haven't tested this yet.

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

No branches or pull requests

2 participants