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

Prevent VM_rint outputting negative zero #226

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

k9ur
Copy link

@k9ur k9ur commented Dec 5, 2024

As the name suggests, VM_rint rounding to an int should output a value that can actually be represented by an int, which negative zero can't.
Previously values from -0.5 to 0.0, including +0, -0, and not -0.5, would round to -0. This meant rounding a value known to be non-negative could output negative zero. This function now outputs +0 for the aforementioned values.

If for whatever reason it's actually intentional that it can sometimes output -0, I'd suggest changing the diff to be just the following (below), so that at least VM_rint(0.0) == 0.0, rather than VM_rint(0.0) == -0.0. It'd then be functionally identical to C's round function as far as I can tell.

-	if (f > 0)
+	if (f >= 0)

Haven't tested the code, unable to, reviewer please do so.

As the name suggests, rounding to an int should output a value that can actually be stored in an int, which negative zero can't.
@terencehill
Copy link
Contributor

Slightly more optimized implementation:

	if (f >= 0.5) // >= 0 works too but it would be slightly less optimized 
		PRVM_G_FLOAT(OFS_RETURN) = floor(f + 0.5);
	else if (f > -0.5)
		PRVM_G_FLOAT(OFS_RETURN) = 0; // prevents negative 0
	else
		PRVM_G_FLOAT(OFS_RETURN) = ceil(f - 0.5);

@terencehill
Copy link
Contributor

Btw, for consistency's sake VM_ceil should be patched too as it returns -0 if input is > -1 and < 0

@k9ur
Copy link
Author

k9ur commented Dec 8, 2024

Btw, for consistency's sake VM_ceil should be patched too as it returns -0 if input is > -1 and < 0

I'm not sure if I agree with that about VM_ceil. To me, it'd make more sense if VM_ceil and VM_floor behaved the same way as C's math.h ceil and floor respectively, and ceil does output -0.
Meanwhile VM_rint isn't named VM_round so I think it's fine to have it behave differently to C's round.

Thanks for the optimization, I'll change the diff to that later, after a maintainer responds to my comment:

If for whatever reason it's actually intentional that it can sometimes output -0, I'd suggest changing the diff to be just the following (below), so that at least VM_rint(0.0) == 0.0, rather than VM_rint(0.0) == -0.0

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

Successfully merging this pull request may close these issues.

2 participants