IonicWind Software

IWBasic => General Questions => Topic started by: Andy on May 15, 2016, 01:08:32 AM

Title: Differences between INT's, UINT's etc.
Post by: Andy on May 15, 2016, 01:08:32 AM
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.



Title: Re: Differences between INT's, UINT's etc.
Post by: LarryMc on May 15, 2016, 01:59:40 AM
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
Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on May 15, 2016, 03:14:48 AM

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.
Title: Re: Differences between INT's, UINT's etc.
Post by: LarryMc on May 15, 2016, 08:38:20 AM
Int64 and Uint64 work exactly the same way

Int64:   -9223372036854775808 to 9223372036854775807
Uint64: 0 to 18446744073709551615
Title: Re: Differences between INT's, UINT's etc.
Post by: LarryMc on May 15, 2016, 08:47:52 AM
Andy

thanks to you those numbers will now be in the next release of the help manual
Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on May 15, 2016, 11:16:39 PM
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.



Title: Re: Differences between INT's, UINT's etc.
Post by: LarryMc on May 16, 2016, 08:46:27 AM
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)
Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on May 16, 2016, 11:41:12 AM
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.



Title: Re: Differences between INT's, UINT's etc. - The PRINT command
Post by: Andy on May 17, 2016, 12:32:29 AM
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.

Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on May 18, 2016, 07:30:55 AM
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.
Title: Re: Differences between INT's, UINT's etc.
Post by: Bill-Bo on May 18, 2016, 04:18:59 PM
Andy,

Try PRINT USING.

Bill
Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on May 18, 2016, 09:53:20 PM
Bill,

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

Andy.
Title: Re: Differences between INT's, UINT's etc. Number to String download
Post by: Andy on May 18, 2016, 11:20:12 PM
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.



Title: Re: Differences between INT's, UINT's etc.
Post by: Bill-Bo on May 19, 2016, 06:36:57 AM
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
Title: Re: Differences between INT's, UINT's etc.
Post by: 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.



Title: Re: Differences between INT's, UINT's etc.
Post by: jalih on May 19, 2016, 09:33:12 AM
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.
Title: Re: Differences between INT's, UINT's etc.
Post by: 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?

Thanks anyway,

Andy.
Title: Re: Differences between INT's, UINT's etc.
Post by: jalih on May 20, 2016, 06:17:49 AM
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.
Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on May 20, 2016, 09:37:10 AM
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.
Title: Re: Differences between INT's, UINT's etc.
Post by: jalih on May 20, 2016, 10:55:51 AM
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.
Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on May 21, 2016, 02:47:43 AM

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.


Title: Re: Differences between INT's, UINT's etc. NumToString2 Download.
Post by: Andy on May 21, 2016, 05:38:25 AM

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.
:)
Title: Re: Differences between INT's, UINT's etc.
Post by: Egil on May 21, 2016, 12:55:18 PM
Andy,

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


Egil
Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on May 21, 2016, 11:36:21 PM
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.
Title: Re: Differences between INT's, UINT's etc.
Post by: Egil on May 22, 2016, 03:31:27 AM
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
Title: Re: Differences between INT's, UINT's etc. NumToString2 Download.
Post by: jalih on May 23, 2016, 02:03:14 PM
Quote from: Andy on May 21, 2016, 05:38:25 AM
So now I have to work on numbers bigger than 4294967295.... that's the next challenge.

With little inline assembly, using the FPU to store number as packed BCD number and then converting from the packed BCD format to a null-terminated alphanumeric string gives you 18 digits precision...
Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on May 23, 2016, 10:09:25 PM

I was also coming to the conclusion that assembly might be needed at this point.

Assembly was the first language I was shown at school when I was 13, and I touched it again at university - however I cannot remember now how to program in it.

Guess this could take a long time to get past this point - unless someone can help.  ???

Thanks,
Andy.
:)
Title: Re: Differences between INT's, UINT's etc.
Post by: jalih on June 01, 2016, 11:27:58 AM
Quote from: Andy on May 23, 2016, 10:09:25 PM
Assembly was the first language I was shown at school when I was 13, and I touched it again at university - however I cannot remember now how to program in it.

Here is my first attempt for using FPU and BCD numbers to replace STR$...


int64 i
i = -123456789012345678q 'Negative number with 18 digits

string s

_asm
  segment .data
  num dt 0.0
  segment .text

  push esi
  push edi

  finit
  fild qword[$i]
  fbstp [num]

  lea esi,[num+9]
  lea edi,[$s]
  mov eax, 0
  fwait

  mov al, [esi]
  dec esi
  or al, al
  jns @@1
  mov al,'-'
  stosb
@@1:
  mov ecx, 8
@@2:
  mov al, [esi]
  dec esi
  or al,al
  jnz @@3
  dec ecx
  jnz @@2

  mov al, "0"
  stosb
  jmp done
@@3:
  test al, 0f0h
  jz digit2
digit1:
  ror ax, 4
  add al, 30h
  stosb
  shr ax, 12
digit2:
  add al, 30h
  stosb
  mov al, [esi]
  dec esi
  jz done

digit12: 
  mov ah, al
  shr al, 4
  and ah, 0fh
  add ax, 3030h
  stosw
  mov al, [esi]
  dec esi
  dec ecx
  jnz digit12

done:
  mov al, 0
  stosb

  pop edi
  pop esi
_endasm


print s

do:until inkey$ <> ""


Title: Re: Differences between INT's, UINT's etc.
Post by: Brian on June 01, 2016, 12:17:42 PM
Wow - goes right over my head! But well done!

Brian
Title: Re: Differences between INT's, UINT's etc.
Post by: srvaldez on June 01, 2016, 03:10:10 PM
hello jalih
your program does not work with the full range of int64, I imagine it would take some effort to make it work as fbstp only outputs 18 digits.
Title: Re: Differences between INT's, UINT's etc.
Post by: Andy on June 01, 2016, 11:21:56 PM
Jalih,

I like the attempt!

However, as I've said before you cannot push a number larger than 18446744073709551615 (16 F's) to a uint64, It's too big.

And in any case, how on earth could you "add" a letter to a number?

What's my obsession with the number 18446744073709551615? - it represents the largest value a qword can have in the windows registry 0xFFFFFFFFFFFFFFFF.

However you may want to work with a number larger than 18446744073709551615 and then +, -, *, / will not work.

We need C's equivalent of a long or long long variable to work with such large numbers.

If you want to work with numbers greater than 18446744073709551615, you need to use my StringMap library, here you have +, -, *, / functions, but it does however need the number as a string, and returns a string for any maths operations used as the result  - that's the best I can do, and it took me a very very long time to write these functions (so you don't have to).

Thanks,
Andy.
:)