May 01, 2024, 12:18:41 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Differences between INT's, UINT's etc.

Started by Andy, May 15, 2016, 01:08:32 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Andy

May 15, 2016, 01:08:32 AM Last Edit: May 15, 2016, 01:15:40 AM by Andy
I woke up this morning with a brain wave (a rare event for me), I realised that although my StringMap library can work with large numbers, it does of course return the answer as a string.

And I thought that someone might actually want that result as a value rather than a string.

So I've created a new routine called SMVal that takes a string such as "4294967295" Hex value FFFF FFFF, and returns the value 4294967295.

The return value is a UINT type variable called say... MyValue.

If I declare a variable X as INT and then say X = MyValue, X becomes -1.

Why is that exactly, and what's the difference between the two types of variables?

I've read the help file and the only difference stated is one is signed and the other unsigned.

I've also found 4294967295 is the largest number these variable types can handle, am I correct on this?

Thanks,
Andy.



Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

LarryMc

UINT stands for unsigned integer
this means there is no bit used to designate polarity so you can only have positive numbers
therefore the number range is from 0 to 4294967295

INT stands for signed integer
this means there is a bit used to designate polarity and it is the most significant bit
when it is set the number is negative
that is why when you take 4294967295 and put it in a INT type variable it becomes -1
the range of an INT is â€"2147483648 to 2147483647

The same sort of thing happens with a CHAR (unsigned) 0-255 and
SCHAR (signed) -127 to 127

Hope that helps
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Andy


Perfect - the penny drops for Int's and Uint's!

But that leads me to INT64 and UINT64, is the limit the same for them too?

I only ask because Int and Uint are 4 bytes, Int64 and Uint64 are 8 bytes.

Thanks,
Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

LarryMc

Int64 and Uint64 work exactly the same way

Int64:   -9223372036854775808 to 9223372036854775807
Uint64: 0 to 18446744073709551615
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

Andy

thanks to you those numbers will now be in the next release of the help manual
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Andy

May 15, 2016, 11:16:39 PM #5 Last Edit: May 15, 2016, 11:48:35 PM by Andy
Larry and all,

I did some testing this morning, and these details should be of interest to all...

Maths operations using +, - , *    ----- maximum return value 4294967295

Maths operations using /             ----- maximum return value 2147483647

STR$ acts like an Int                  ----- maximum return value 2147483647

VAL                                        ----- maximum return value 18446744073709537000

GETCONTROLTEXT                     ----- maximum return value - none as far as I can see.

HEX$                                      ----- maximum return value 4294967295

ABS                                        ----- maximum return value  2147483648 (Hex 8000 0000)

So,

You although may have a number 4294967295, the maximum number str$ can use is 2147483647

If you use Uint64 and have the number 4294967299 and use - (minus) to subtract 1 in a loop, the return value will be incorrect until you get down to 4294967295, and then it's fine.

If you have the number 4294967291 and use + (add) to add 1 in a loop, the return value will be fine up to and including 4294967295, after that the numbers are incorrect.

If you use * (multiply), that's fine as long as the result is less than or equal to 4294967295.

If you use / (divide), as long as the number is less than or equal to 2147483647 it will work, however if the number is bigger i.e. 2147483648 - it won't work.

Thanks,
Andy.



Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

LarryMc

are you sure about the HEX$ value? it's suppose to work with INT64

also, I don't see any negative values anywhere (excluding ABS of course)
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Andy

May 16, 2016, 11:41:12 AM #7 Last Edit: May 16, 2016, 11:56:52 AM by Andy
I've had another look, and this is what I've found....

If you make x an Int64 - Hex$ returns 16 F's for 4294967295 (wrong).

If x is an Uint - Hex$ returns 8 F's (correct)

If x is an Uint64 - Hex$ returns 16 F's (wrong).

And I've only tested on positive numbers so far.

This is why for Dwords in the registry I can work out the decimal value of the entry, but for Qwords (double the size of Dwords) no I can't, only if they have a decimal value is up to and no greater than FFFF FFFF, beyond that I'm lost.

Andy.



Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Andy

The PRINT command...

Althought Uint64 can be 0 to 18446744073709551615, if I try and print x, where x = 12345678901
I get the wrong number printed in a console program.

If x = 1234567890, then it prints 1234567890.

So, is x set correctly as 12345678901 or larger, or is it the print command just not displaying the correct number?

If I make x DOUBLE, then it prints 12345678901 or larger....

If I make x UINT64, and set x to 12345678901 or larger, and make y DOUBLE and say y = x... it doesn't print correctly again.

So after typing this, it looks like UINT64's have the problem?

My main question is how can I make sure a DOUBLE has .00 included in it?  - I am working on a routine to convert large numbers to strings, which it now does, however, on a large number I have to make sure there is .00 on the end.

Example  

Double D

D = 12345678901234.00 - works
D = 12345678901234 - does not.

Is this a Job for _printf?, and if so how do I use it?



Thanks,
Andy.

Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Andy

May 18, 2016, 07:30:55 AM #9 Last Edit: May 18, 2016, 09:45:51 AM by Andy
I have also found that as long as a unit64 is assigned a number <= 2147483647 you can use the + operator to add to it (as long as each addition is <= 2147483647).

e.g.

uint64 fVar = 0

for y = 1 to 80000000
   fVar += 2147483647
next y

However, if you want to assign a number directly to a uint / double, and it is greater than 2147483647, you must add .00 to it

i.e. fVar = 744073709551615.00


openconsole

uint64 fVar = 0

fVar += 744073709551615.00

print
print
print " Number ",fVar
waitcon
end



So the question remains .....

How do I add a .00 to a double / uint64
 ???

And isn't trying to add .00 to a uint a contradiction in terms  ???

Thanks,
Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Bill-Bo


Andy

Bill,

That's a good try, but the number is too big for both USING and SETPRECISION commands.

Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Andy

Attached is an example of how to convert a large number to a string.

The .lib file goes in your libs folder, and the .inc file goes in your include folder, then you can compile the program.

Although I'm still puzzled as to why a number larger than 2147483647 needs .00 on the end to be directly assigned to a double variable.

Thanks,
Andy.



Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Bill-Bo

Andy,

Maybe I missed something. Why are you needing .00 at the end of such large numbers? What kind of monies program are you working on that requires that much?

Bill

Andy

Bill,

I'm simply trying to set a double variable like this

double d

d = 2147483648 (does not work)

but you can only do it up to the number 2147483647

d = 2147483647 (works)

If the number is greater than 2147483647 you have to do it this way:

d = 2147483648.00 (works)

I'm simply trying to write my own version of str$ which can copy with larger numbers than str$ that's all.

Andy.



Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

jalih

Quote from: Andy on May 19, 2016, 08:43:29 AM
Bill,

I'm simply trying to set a double variable like this

double d

d = 2147483648 (does not work)

but you can only do it up to the number 2147483647

d = 2147483647 (works)

If the number is greater than 2147483647 you have to do it this way:

d = 2147483648.00 (works)

I'm simply trying to write my own version of str$ which can copy with larger numbers than str$ that's all.

Andy.

Compiler defaults numeric literals without decimal as INT and numeric literals with decimal part as DOUBLE. You need to use numeric modifiers, check Constants and Literals topic from the manual.

Andy

Jalih,

That's another good attempt, however I would still need to add something to the end of the number such as buq or .00 etc.

So the question still remains, how do you add something to a number when you do not know what that number is?

Thanks anyway,

Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

jalih

Quote from: Andy on May 20, 2016, 01:35:26 AM
Jalih,

That's another good attempt, however I would still need to add something to the end of the number such as buq or .00 etc.

So the question still remains, how do you add something to a number when you do not know what that number is?
Why do you feel the need to add something to a number? Numeric modifiers are only needed for numeric literals, also known as numeric constants. Compiler knows how to handle number in variable just fine based on it's type.

Andy

Jalih,

All my testing to date shows, that no matter how you modify a number, if the number is greater than 2147483647 it just does not work unless it has .00 on the end.

If you start with a number < = 2147483647 that's fine.
If you add to it and the number <= 2147483647 that's fine.

If you start with a number (or add to it) and the number is > 2147483647 it does not work.

I'm simply trying to turn a large number into a string, something that str$ cannot do above 2147483647.

I've been working on my library called StringMap, it started with the idea of working with strings and it has nearly 300 functions that would take someone a lot of coding to do, and it takes the work out of it for you.

I noticed the limit of str$, and that's why I'm trying to break that limit.

BTW, It's nice to see new members - welcome!

Thanks,
Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

jalih

Quote from: Andy on May 20, 2016, 09:37:10 AM
I noticed the limit of str$, and that's why I'm trying to break that limit.

How about using C library, something like:


double i
i = 2147483648.0
print MySTR$(i)
do:until inkey$ <> ""


SUB MySTR$(double d), string
  DECLARE CDECL EXTERN _sprintf(buf as STRING, format as STRING, ...),INT
  string s
  _sprintf(s, "%.2f", d)

  RETURN s
ENDSUB


You could also probably define function parameter as ANYTYPE and handle needed conversion based on type of the variable.

Andy


I've been looking at the C functions to try and get past this....

If you use your code it works because i is set to 2147483648.0 (with a .0), if you take the .0 away it doesn't work.

i = 2147483648

openconsole

print MySTR$(i)
do:until inkey$ <> ""
waitcon

end


SUB MySTR$(double d), string
  DECLARE CDECL EXTERN _sprintf(buf as STRING, format as STRING, ...),INT
  string s
  _sprintf(s, "%.2f", d)

  RETURN s
ENDSUB


So problem 1 is if the number is > 2147483647 you need the .0
problem 2 is that if you add to the previous number and it is > 2147483647 you also need the .0 added to it.


Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Andy


I've now managed to take any number from 0 to 4294967295 inclusive and turn it into a string.

So now I have to work on numbers bigger than 4294967295.... that's the next challenge.

Attached is the program, as always .lib to your IWB's libs folder, .inc to your IWB's include folder (both found in C:\Program Files\IWBDev).

Thanks,
Andy.
:)
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Egil

Andy,

Just a little off topic question...
Do you ever sleep?


Egil
Support Amateur Radio  -  Have a ham  for dinner!

Andy

Egil,

QuoteDo you ever sleep?

I'm one of these people that usually get up around 5.30am, I do keep an eye on what's being posted just in case it may come in useful, but yes I do sleep, I'm not yet like the Terminator, just a dog with a bone when I get into something - I can't leave it!  ;D


Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

Egil

Quotejust a dog with a bone when I get into something - I can't leave it!

Just like me, but  I usually fiddle with my radios that early... ;D
Support Amateur Radio  -  Have a ham  for dinner!