suggestion: big numbers

Started by Captain Mostly, Thu 28/07/2005 15:48:12

Previous topic - Next topic

Captain Mostly

I suppose not MANY people will have come acropper with this, but in vegetable patch extreem Turbo 1 & 2 (and now Vegetable Patch Extreem Tarrot) the limit of having numbers that only go up to 2,147,483,647 is jolly frustrating. It's not at all difficult for people to exceed this as a score in the vegetable patch games and as far as I can see there's no easy way of getting round it (the Patch Turbo games had a "MAXED OUT" feature that explained you'd scored a bigger number than the computer could think of, but it wasn't satisfactory at all).

I just wondered how difficult it would be to have a capacity for 64bit numbers available. I suppose I'd be the only person who'd apreciate it, so if it's a jolly complicated task, don't worry... It'd just be really really handy!  :=

Pod

Does AGS support unisnged variables? If so use unsigned int instead of int. Or "double" if AGS supports it..

monkey0506

AGS supports "long" variables although it's not covered in the manual.  It may just be #define-d as int, so I'm not sure, but if it is supported properly then it should be able to go up to 9223372036854775807 (according to the C++ book I've been using).  And I don't suppose you would need a higher number than that...

But, alas, I have just tested it, and it would seem that long is in fact #define-d as int...Anything higher than 2147483647 loops back around to the negative range (i.e., 2147483648 = -2147483648, 2147483649 = -2147483647, 2147483650 = -2147483646, etc.)

And BTW Pod, neither unsigned or double are AGS recognized keywords.

DoorKnobHandle

With AGS 2.7 you could also use floats.

Simply add 0.0000001 to the score instead of 1 and you will be able to have 1000000x higher numbers, I think...

RickJ

Well, if it's just to keep track of a score you could script it yourself using a pair of ints or a char array.     

Captain Mostly

the problem that I have with char arrays or two ints is that multiplying and dividing etc become a lot more complicated than they should have to have been - and I'm frankly a bit too shit at programming to keep track of amount of number juggling!  :-[

I'm not sure that using a float would increase the score range... As far as I remember it's still a 32 bit number so it woouldn't work that it'd be able to think of 2,147,483,647.0000001 because of the leangth of it... I don't THINK... Can anyone clear this up? if it COULD think of 2,147,483,647.0000001 (and thus, presumably, anything lower than it with a similar number of decimal places) it WOULD solve the problem (I think...)

However, something more akin to the "long" variable monkey discovered doesn't exist would be RIGHT up my alley! Alas, 'tis not to be!

Pumaman

floats can store larger numbers but they lose precision, so for each digit you add to the left, the far right digit effectively becomes 0...

so if you tried to store:
4,232,147,483,647
you'd get:
4,232,147,483,000

Anyway, 64-bit long support is a possibility, but practically speaking it's not really in demand enough to warrant the time.

However, you can simulate it yourself by using two ints, eg:

int millions;
int units;

and wrap around the units at 1000000 and increment the millions.
It's a bit of work, but possible.

fanton

#7
you could use abacus style programming. i invented the word but not the idea. what that means is when you reach a limit, you have another variable to be flagged 1 or accumulate in another variable the carry.

the truth is that you can use almost any language to do anything you want. there is always a limit. but you can always get away. at least mathematically.

that is how the processor does the division or multiplication, by iterating pieces of data. the register can hold some values. i programmed a 8 bit register for a motorola chip and you could do any calculations by spliting the values. i could add the numbers below using 8 bit registers. which means adding the number below with limits up to 255.

a number like 4,294,967,294 which is beyond the limit?
may becomes something like

int billions = 4
int millions = 294
int thousands = 967
int tens = 294

if you want to do some arithmetic on that then you start from the lower value and up. if you multiply that but a number like 13,540

4,294,967,294 * 13,540 = 58,153,857,160,760

that means

tens * 540 = 158,760
or tens = 760
carry = 158

multiply thousands
tens * 13 = 3,822
thousands * 540 = 522,180
thousands * 13 * 1000 = 12,571,000
thousands = 3,822 + 522,180 + 12,571,000 + 158 (carry) = 13,097,160
or thousands = 160
carry = 13,097

in assembly you cannot do this. numbers like 3,822 have to be re-run. you still need some memory to store the ongoing calculations. i had about 64k but i never used numbers this big. anyway, continuing.

multiply millions
tens * 0 = 0
millions * 540 = 158,760
millions * 13 *1000 = 3,822,000
millions = 158,760 + 3,822,000 + 13,097 = 3,993,857
millions = 857
carry = 3,993

multiply billions
billions * 540 = 2,160
billions * 13 * 1000 = 52,000
billions = 2,160 + 52,000 + 3,993 = 58,153
therefore billions = 153
carry = 58

and the answer is
carry billions millions thousands tens
58 153 857 160 760

and the original was
4,294,967,294 * 13,540 = 58,153,857,160,760

so you see, you can do any number of calculations with any limit. the 4 billion is not a real number, is more a fragmented number, but you can still use division, multiplications, etc. the whole operation is but a simple repetition, you can make a function called long_mult(term1, term2), or you can make lond_div.

you can evem make your own struct

typedef struct {
int trillions
int billions
int millions
int thousands
int tens
} long_int;

long_int number;
long_int.thousands = somestuff.

if you can think it, you can achieve it, is just not very obvious. this is one answer to your question.

fanton

#8
1. another sollution is to substract some large value.

for example 3 billions could be some -5, by 3 billions - some large value.

more detail.

4,232,147,483,647 cannot be used  but you can convert it to a smaller number by taking out half of 4,232,147,483,000 (which is the largest? value)

and you have 2116073742147  to use  :P

in which case you would have the negative and positive side of the int.

a number like 5 can become -2116073742142 which can be used. so you have twice the amount of numbers. but you CANNOT use negative numbers. and you have to play tricks to do multiplication, because it is unsigned.

it might work, i think, somewhat. but i did not think of all details. theoretically sounds cool, but practically buying some nutella would yield better results. which would make your brain work better because all the shugars. so buy nutella before trying.

2. and yet another workaround is to call an external program to do the calculations, day of the tentacle style! but i don't know if that would work. i think it might be able to work. if you can open files, or do some sort of switching to other program, multi-tasking, threading?, i forgot the function's name that one used to replace the program with another program but only on unix.

you could run the game from an outside program. and have some sort of file, pipe, interface. and put stuff to calculate in one place, have the second program (calculating one) look trough continously to see if is there anything to calculate. and when the calculations are done, have it put the answer in anther place.

and the making sense way:
a program rungame.exe calls mygame.exe (the ags executable) and calculator.exe and create two files calcin.txt and calcout.txt. the calculator.exe looks trough calcin.txt to see if there is anything to do and puts answers in calcout.txt. mygame.exe is the ags executable, it opens the mycalcin.txt and puts instructions there whenever is needed, waits a while and looks in calcout.txt, takes the stuff and displays laughing characters and tarrot cards and a happy programmer.

when mygame.exe goes away, rungame.exe deletes the files, closes the calculator and shuts the lights. all is quiet.

the above will work becaue most operating systems are multi-tasking, multi-treading, a lot of stuffing in the same timing. you can replace the files with pipes.

3. there is a program called bc on unix. see if you find a port for windows or sourcecode. it does calculations with infinite numbers. not infinite, but any number of numbers :P i think is called bc. has a diffrent type of calculating. see how they do the stuff. and is very precise. its hard to use. you can even redirect stuff into it. on linux is very easy to make steps 2 and 3.

http://unixhelp.ed.ac.uk/CGI/man-cgi?bc+1

Captain Mostly

#9
Well... Ok... avatar's suggestions sound jolly complicated and it'll take me a bit to take them all in... but in response to CJ's suggestion:

I see the logic of it... And I guess it wouldn't be TOO hard to implement an "increase score" function... And now I think about it, you could display it via

StrFormat(ScoreString,"%d%d", millionsscore, unitsscore); couldn't I?

Thankyou! :)

[EDIT]... oh, but I've just thought.... if I say that unitsscore only goes up to 999999 so that one million 7 hundred and sixty five thousand nine hundred and ninty nine is shown as:
1 := 765999 with an invisible gap where the larry is, how do I THEN lay it out so that when I just want one million and one it doesn't look like THIS:

1 :=Ã,  Ã,  Ã,  1

instead of

1 := 000001
?!?!?

RickJ

Try doing somethoing like this:

StrFormat(ScoreString,"%06d%06d", millionsscore, unitsscore);


Captain Mostly

would that work?! if so - BUMS! I spent AGES on elaborate if statements last night... Oh well.

It works now, and I think I've shifted the maximum score up to 2,147,483,647,999,999

I COULD go up to 2,147,483,647,999,999,999 but I think I can't be bothered with changing all the code AGAIN - maybe next time eh?

Thankyou for you help everyone! It might be a huge faff compared to just having a bigger int, but I guess I AM the only one who'd use it, oh well!  :)

SMF spam blocked by CleanTalk