Page MenuHomeFeedback Tracker

Integer greater/lesser than comparison can give incorrect result when one number is negative
Closed, ResolvedPublic

Description

E.g. the following comparisons evaluate to true but shouldn't:

120 < -2147483647;  // true
1 < -2147483647;  // true
2147483647 < -1;  // true
// etc

Conversely, the following evaluate to false:

120 > -2147483647;  // false
1 > -2147483647;  // false
2147483647 > -1; // false
// etc

Details

Severity
Major
Resolution
Open
Reproducibility
Always
Operating System
Windows 10 x64
Category
Scripting
Steps To Reproduce
Print("Integer comparison testing START");
int start = 1;
for (int f = start; true; f++)
{
	if (f > -2147483647)
	{
		Print(f.ToString() + " > -2147483647");
		break;
	}
	if (f == 2147483647)
		break;
}
Print("Integer comparison testing END");
Print(f);

Will never hit the condition where f is bigger than -2147483647, despite f starting positive and growing (note that the loop does finish fine, just takes a while).

Additional Information

Once the compared number reaches int.MIN + <other number> + 1 (for greater than comparison) or int.MAX - <other number> (for lesser than comparison), the comparison starts to give correct results again.
E.g.:

10 > int.MIN;  // false, incorrect result
10 > int.MIN + 10;  // false, incorrect result
10 > int.MIN + 11;  // true, correct result
-10 < int.MAX;  // false, incorrect result
-10 < int.MAX - 10;  // true, correct result

Event Timeline

lava76 created this task.Aug 11 2022, 3:58 PM
Liven added a subscriber: Liven.EditedAug 11 2022, 11:16 PM

@lava76 Maybe you should take a look on this: https://community.bistudio.com/wiki/Arma_Reforger:Scripting:_Values (Primitive Types part)
The scripting language is the same than dayz

I don't remeber where in the documentation, it says when limit is reach it behave like this:
2147483648 +1 = -2147483648
(No infinite numbers possible because no infinite computing possible).

lava76 added a comment.EditedAug 12 2022, 1:50 PM

The problem is not infinite recursion.
The problem is that 1 < -2147483647 should NOT evaluate to true, ever (or any other positive non-zero number that's in-range for a 32-bit int).

I wouldn't be surprised if the underlying problem has very wide spread consequences that would explain a lot of oddities I've been seeing in integer math in Enforce

lava76 added a comment.EditedAug 14 2022, 1:07 PM

Work-around for comparison:

//! @brief Compares two numbers
//! Returns 1 if a > b, zero if a == b and -1 if a < b
static int Cmp(int a, int b)
{
	if (a == b)
	{
		return 0;
	}
	else if ((a >= 0 && b >= 0) || (a < 0 && b < 0))
	{
		if (a > b)
			return 1;
		else
			return -1;
	}
	else if (a < 0 && b >= 0)
	{
		return -1;
	}

	return 1;
}

(Edit: simpler version of the above, just convert to float for the comparison)

//! @brief Compares two numbers
//! Returns 1 if a > b, zero if a == b and -1 if a < b
static int Cmp(int a, int b)
{
	if (a == b)
		return 0;

	float af = a, bf = b;

	if (af > bf)
		return 1;

	return -1;
}
lava76 renamed this task from Integer comparison and arithmetic seem broken to Integer greater/lesser than comparison can give incorrect result when one number is negative.Aug 27 2022, 2:01 PM
lava76 updated the task description. (Show Details)
lava76 edited Steps To Reproduce. (Show Details)
lava76 edited Additional Information. (Show Details)
lava76 added a subscriber: Geez.Sep 23 2022, 1:09 PM

@Geez sorry for the ping, any update on this?

Looks like it's fixed in 1.19 Experimental.

Geez closed this task as Resolved.Sep 29 2022, 12:03 PM
Geez claimed this task.