Short Single?
Short Single?
Hello.I know, that compared to QBasic, FreeBasic has more datatypes.
For example: old QB 16bit Integer is now 32bit Integer, and 16bit Integer is Short or Integer<16>. There is also long and byte. And UInteger,Ushort etc...
But what about Single/Double? Single is 32bit and Double is 64.
Single allow 6 decimal digits while Double allow 15.
Is it possible to have Single/Double as 16bits data type?
And something like USingle and UDouble, becouse sometimes I need variable that use for example just numbers from 0.0 to 10.0 or from 0 to 1 with one or two digits.
For example: old QB 16bit Integer is now 32bit Integer, and 16bit Integer is Short or Integer<16>. There is also long and byte. And UInteger,Ushort etc...
But what about Single/Double? Single is 32bit and Double is 64.
Single allow 6 decimal digits while Double allow 15.
Is it possible to have Single/Double as 16bits data type?
And something like USingle and UDouble, becouse sometimes I need variable that use for example just numbers from 0.0 to 10.0 or from 0 to 1 with one or two digits.
-
- Posts: 4292
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
-
- Posts: 1186
- Joined: May 08, 2006 21:58
- Location: Crewe, England
Re: Short Single?
It's important to understand that a Single / Double is not held in decimal, but as a binary fraction, and one byte is taken by one bit for the sign and 7 bits for the power of 2 by which the fraction is to be raised. A single can hold a whole number up to a bit over 16 million decimal. Note also that any figures after the deimal point will be converted to a binary fraction, i.e. 1/2+1/4+1/8 etc, so 1/10, because it involves a power of 5 will be an approximation. a Double has an extra 32 bits of precision (significant figures), but the same rule applies.
I did once work at a company which had devised a 16-bit floating point number, to store figures from published company accounts, which are already approximations. That was in the days when disk storage was expensive.
I did once work at a company which had devised a 16-bit floating point number, to store figures from published company accounts, which are already approximations. That was in the days when disk storage was expensive.
Re: Short Single?
There are so called: Half-Floats (16bit) but not in FreeBASIC (not a basic data-type).
Unsigned Floats (of any size) whould break their 'design' which is 'IEEE 754 Standard'.
Currently published last time in 2020. See details: Wikipedia > IEEE 754
Unsigned Floats (of any size) whould break their 'design' which is 'IEEE 754 Standard'.
Currently published last time in 2020. See details: Wikipedia > IEEE 754
Last edited by MrSwiss on Sep 10, 2021 17:39, edited 1 time in total.
Re: Short Single?
Keep in mind that a signed 16-bit integer only has slightly more than 4 digits precision. Start taking bits off for a floating point exponent, and you quickly end up with no precision
Half floats are mainly used for AI interference matrices, where it is more magnitude (one/two digits+exponent). Only fairly new GPUs (not CPUs) support them as it is a fairly new type.
Half floats are mainly used for AI interference matrices, where it is more magnitude (one/two digits+exponent). Only fairly new GPUs (not CPUs) support them as it is a fairly new type.
Re: Short Single?
In old QBasic integers were 16 bit; in FreeBasic, they are usually either 32 or 64 bits (depending on the architecture), but in "lang qb" they are 16 bit long, for compatibility (so, if a file has been created with a Quick Basic program, and that program is recompiled with FreeBasic, it can still read the same file)
Regarding floating point numbers, even old QBASIC already used 32 bit or 64 bit values, so there is no real reason to support 16 bit formats.
Actually, for floating point numbers, there were more formats in the past than today: in fact, in 16 bit era, most computers didn't support floating point numbers in hardware (to do that, you needed an external math coprocessor). For that reason, floating point numbers required softare routines to process them, and they could be stored in any format: one widely used format was the MBF (Microsoft Binary Format, used in GW Basic); the IEEE 754 was only one of the possible formats.
With more modern processors, the math coprocessor was integrated in the main CPU, and was called FPU (Floating Point Unit): since it used the IEEE 754 format, all other formats were abandoned, being unable to take advantage of the hardware. Even Microsoft Basic had to switch to the new format (old Quick Basic still provided the /MBF option to be able to read floating point numbers stored in the obsolete MBF format)
If you need a floating point number that uses only 16 bytes (or even only 8 bytes) it could be done using an user defined data type (class). But precision would be too low to be useful in most situations
Regarding floating point numbers, even old QBASIC already used 32 bit or 64 bit values, so there is no real reason to support 16 bit formats.
Actually, for floating point numbers, there were more formats in the past than today: in fact, in 16 bit era, most computers didn't support floating point numbers in hardware (to do that, you needed an external math coprocessor). For that reason, floating point numbers required softare routines to process them, and they could be stored in any format: one widely used format was the MBF (Microsoft Binary Format, used in GW Basic); the IEEE 754 was only one of the possible formats.
With more modern processors, the math coprocessor was integrated in the main CPU, and was called FPU (Floating Point Unit): since it used the IEEE 754 format, all other formats were abandoned, being unable to take advantage of the hardware. Even Microsoft Basic had to switch to the new format (old Quick Basic still provided the /MBF option to be able to read floating point numbers stored in the obsolete MBF format)
If you need a floating point number that uses only 16 bytes (or even only 8 bytes) it could be done using an user defined data type (class). But precision would be too low to be useful in most situations
Re: Short Single?
Thanks for info. Good to know.
Few years ago I was programming little game in QBasic. And most problematic was floats numbers. Even Single was sometimes too precise :-)
For example when printing they are too long, ( always need to round it or use PRINT USING)
So I was avoided using Single/Double and hold data in integers
then print x/1000
But for basic tasks like simple games numbers like 0.005 (1/200) is enough. No need to use something like 0.005025125628140704 (1/199)
Few years ago I was programming little game in QBasic. And most problematic was floats numbers. Even Single was sometimes too precise :-)
For example when printing they are too long, ( always need to round it or use PRINT USING)
So I was avoided using Single/Double and hold data in integers
then print x/1000
But for basic tasks like simple games numbers like 0.005 (1/200) is enough. No need to use something like 0.005025125628140704 (1/199)
-
- Posts: 1186
- Joined: May 08, 2006 21:58
- Location: Crewe, England
Re: Short Single?
Another option worth considering is holding data in integers, but representing thousandths of whatever the variale is supposed to be. If you need to display these variables, write your own editing routine to place the decimal point and any leading zeros.
Re: Short Single?
jevans4949 wrote:Another option worth considering is holding data in integers
Code: Select all
function GetHalf naked cdecl(byval s as short) as single
asm
fild word ptr [esp+4]
push 10000
fild dword ptr [esp]
fdivp
pop eax
ret
end asm
end function
Print "Short=";GetHalf(31416)
Sleep
Re: Short Single?
The printing issue can pretty easily be fixed, by using a 'self written' custom function.BasicJedi wrote:For example when printing they are too long, ( always need to round it or use PRINT USING)
Deals with Double but can also take Single.
Decimal digits after the delimiter, can be set, from 0 to 9 (default: 2).
It adds "0"'s in case the fraction is shorter than 'ndec'.
(this alowes to print right-justified values, positioned below each other)
NOTE: only the integer return is rounded (ndec = 0), all else is just "chopped off".
This is what I currently use:
Code: Select all
' Fit2nDec_proc.bas -- (c) 2021-05-15, MrSwiss
'
Function Fit2nDec( _ ' chop double to set number of decimals
ByVal v_in As Double, _ ' input value
ByVal ndec As ULong = 2 _ ' number decimals (default = 2)
) As String
If ndec > 9 Then ndec = 9 ' force max. number of decimals
If ndec = 0 Then ' when no fraction wanted ...
Return Str(CLngInt(v_in)) ' string (rounded longint)
Else
Var fs = Str(Frac(v_in)) ' string
Var s = Right(fs, Len(fs) - IIf(v_in < 0.0, 3, 2)) ' string
Var ls = Len(s) ' integer
If ls > ndec Then s = Left(s, ndec) ' chop fraction off (no rounding)
While ls < ndec ' if fraction to short
s += "0" : ls += 1 ' add zero | increment ls
Wend
Return Str(Fix(v_in)) + "." + s ' concatenate result
End If
End Function
-
- Posts: 1186
- Joined: May 08, 2006 21:58
- Location: Crewe, England
Re: Short Single?
There is an IEEE specification for decimal (as opposed to binary) floating point numbers, but I don't know if anybody has ever implemented it, in software or hardware.
Re: Short Single?
BCD floating point hardware existed yes. Even x87 has some (load/store) support:jevans4949 wrote:There is an IEEE specification for decimal (as opposed to binary) floating point numbers, but I don't know if anybody has ever implemented it, in software or hardware.
Note to OP: if you don't really need floating point, a fixed point value is sometimes also used. This is less dynamic, but if all you want is multiplying integers by small factors (e.g. 1.3) then it can be useful and efficient on embedded systems.Wikipedia wrote: In x87
See also: Intel 8087 § IEEE floating-point standard
The x87 coprocessor has BCD support in the form of a pair of load (FBLD) and store-and-pop (FBSTP) instructions. The former loads a 80-bit BCD integer into the FPU, while the latter writes a FPU value as a 80-bit integer value into the memory. Inside of the FPU, the values are stored as normal x87 extended-precision floats. Unlike the integer-facing versions, the two instructions remain available in long mode.
Re: Short Single?
hello jevans4949
D.J.Peters wrote a fixed-point package viewtopic.php?p=200294#p200294
Intel wrote and released a BCD math library viewtopic.php?f=14&t=29203
IBM also came out with DecNumber and there's mpdecimal, but the library by Intel is the most versatile
D.J.Peters wrote a fixed-point package viewtopic.php?p=200294#p200294
Intel wrote and released a BCD math library viewtopic.php?f=14&t=29203
IBM also came out with DecNumber and there's mpdecimal, but the library by Intel is the most versatile
-
- Posts: 1186
- Joined: May 08, 2006 21:58
- Location: Crewe, England
Re: Short Single?
I stand enlightened.
Re: Short Single?
Going the other way, it looks like the crt double has one more place than the fb double.
Code: Select all
#include "crt.bi"
Function _str(Byval x As Double) As string
static As zstring * 32 t
sprintf(t,"%.30f",x)
if instr(t,".") then
t=rtrim(t,"0")
Return rtrim(t,".")
else
return t
end if
End Function
#define _round(x,N) rtrim(rtrim(left(_str((x)+(.5*sgn((x)))/(10^(N))),instr(_str((x)+(.5*sgn((x)))/(10^(N))),".")+(N)),"0"),".")
dim as string s,b
print "rounded(5)";tab(25);"number";tab(50);"crt number";tab(80);"difference"
for x as long=1 to 500
var d=(rnd-rnd)/1000
var f=(rnd-rnd)*10000000000
if rnd>.5 then
s=_round(d,5)
print s;tab(25);d;tab(50);_str(d);tab(80);val(_str(d))-d
else
b=_round(f,5)
print b;tab(25);f;tab(50);_str(f);tab(80);val(_str(f))-f'val(b)-f
end if
next
sleep