[BUG] TBigInt FString constructor doesn't handle overflow

Hey All,

I wasn’t sure which category to post this under, so I did two identical posts to separate sections.

So I’ve found what I believe to be a bug in the BigInt class, but it may be specced this way. Basically, trying to initialize a BigInt with a hex FString gives me unexpected results when the value of the hex string is larger than 65,535.

The following code:

TBigInt&lt128&gt int128_1(“ffff”);

TBigInt&lt128&gt int128_2(“10000”);

UE_LOG(LogTemp, Warning, TEXT("%s"), *int128_1.ToString());

UE_LOG(LogTemp, Warning, TEXT("%s"), *int128_2.ToString());

Produces the output:

LogTemp:Warning: 0x0000ffff

LogTemp:Warning: 0x0000000100000000

Meaning that for values up to and including 65,535 (u16 max), this constructor works, but for any values past that, starting with 65,536, the constructor initializes the BigInt to 4,294,967,296 (u32 max). If this is intended behavior please let me know, because I need to be able to serialize these numbers in and out of a text file. Storing them as hex values works fine until they get larger than 65535. So if this is intended, I need to either write functionality into this class, write my own, or go with GMP.

Thanks!

Branden Turner

Hey -

Could you provide the full code where you’re using TBigInt? I’m receiving undeclared identifier errors when trying to add the code you provided to an actor class.

Cheers

Hey ,

You probably have to include BigInt.h at the top of your file. If it can’t find that header file, then you have to depend on an additional module in your build file, but I’ll include full source when I get near a computer tonight.

Thanks again! Branden

Hey ,

Got to a computer and made a brand new actor c++ class. You just need to include BigInt.h at the top of your c++ file and it’ll compile just fine. Here’s the full code just in case:

// Fill out your copyright notice in the Description page of Project Settings.
#include "ActorTest.h"
#include "BigInt.h"




// Sets default values
AActorTest::AActorTest()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AActorTest::BeginPlay()
{
	Super::BeginPlay();

    TBigInt<128> int128_1("ffff");
    TBigInt<128> int128_2("10000");

    UE_LOG(LogTemp, Warning, TEXT("%s"), *int128_1.ToString());
    UE_LOG(LogTemp, Warning, TEXT("%s"), *int128_2.ToString());
	
}

// Called every frame
void AActorTest::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

}

Hey -

I had the include statement but I found another issue with trying to use the TBigInt inside the Tick() function of a class (something we’ll also look into). In regards to your issue it seems that the value of the string is taking twice as much space as it should. This is what is causing the leading ‘0000’ in both cases and why the second case has so many additional 0’s. I’ve bugged this (UE-18389) for further investigation.

Cheers

Hey !

I had no idea that there was an issue in using it with Tick(), so I’m glad I posted the full source now! Thanks for speedy reply on this. Just to clarify, you’re talking about the zeros on the right side of the 1 in the second statement as well right?

Because even if the leading zeros were there, the “proper” output for the BigInt constructed with “10000” would be 0x0000000000010000 ( without leading zeros would probably be 0x00010000, since it’d add 4 places at a time ) and not 0x0000000100000000. But I’m assuming you mean the other four zeros to the right are due to this issue as well, correct? Because it seems the one is jumping about 4 places to the left that it shouldn’t be.

If these are all connected, which they do seem to be, then great! Just making sure that when I initialize a BigInt in the future with “10000” its string outputs 0x00010000 or 0x10000, whichever is intended, but more importantly that the underlying data is initialized with the correct value.

Thanks again!
Branden

I think I realize what’s going on, and the issues are connected. Basically for each word in your BigInt, you’re printing a string that’s four characters too big. So the four zeros to the right of the 1 that I’m talking about are actually just four leading zeros in the first word, that shouldn’t be there. Makes sense now!

Thanks!

Branden

That is correct. As another example if you use the string (“eeeeffff”) it would currently print out as 0x0000eeee0000ffff. So in the case of your string (“10000”) the first four 0’s after the ‘x’ are unnecessary as are the first four 0’s after the ‘1’.