X = INT(X * 100 + .5) / 100 to round at 2 decimal places.
Seems unnecessarily complicated? Why not the simple:
X = CINT(X * 100) / 100 to round at 2 decimal places?
X = INT(X * 100) / 100 to truncate at 2 decimal places.
X = INT(X * 100 + .5) / 100 to round at 2 decimal places.
FUNCTION RoundTo## (Num AS _FLOAT, Precision AS INTEGER)
RoundTo = INT(Num * 10 ^ Precision + .5) / 10 ^ Precision
END FUNCTION
Hi,
tried the INT version ... 4/3 = 133.3333 ?? both INT solutions give me the same answer
i.e. X = INT(4 * 100 + .5) / 3 or
X = INT(4 * 100) / 3
I would like 1.33 to 2 decimal places
and 4/6 = 1.67 and this rounded
I have tried the string manipulations and it seems to work fine.
Mike
Hi Krovit,
Using your method ... but it only returns the decimal places ... I need the whole number as well.
5/3 = .67 this is great .. but I want the 1.67.
Thks,
Mike
This is way without string conversions. Function parameters are: decimal number, lenghtCode: QB64: [Select]
'1.2345, 2 => 1.23 integernum = num \ 1 decimalnum = num / 1 - num! \ 1 n = 10 ^ lenght newdecimalnum = decimalnum * n newdecimalnum = INT(newdecimalnum) 'or comment this row and rewrite it as newdecimalnum = newdecimalnum \ 1 for rounding outputs. newdecimalnum = newdecimalnum / n LNUM = integernum + newdecimalnum
I added the following to the code and it seems it will not produce a decimal place beyond 6. I'm not sure why that would be.Code: QB64: [Select]
PRINT "1 decimal place "; PRINT "2 decimal places "; PRINT "3 decimal places "; PRINT "4 decimal places "; PRINT "5 decimal places "; PRINT "6 decimal places "; PRINT "7 decimal places "; PRINT "8 decimal places "; PRINT "9 decimal places "; PRINT "10 decimal places "; '1.2345, 2 => 1.23 integernum = num \ 1 decimalnum = num / 1 - num! \ 1 n = 10 ^ lenght newdecimalnum = decimalnum * n newdecimalnum = INT(newdecimalnum) 'or comment this row and rewrite it as newdecimalnum = newdecimalnum \ 1 for rounding outputs. newdecimalnum = newdecimalnum / n LNUM = integernum + newdecimalnum
Its because it is SINGLE precision. Try DOUBLE, or FLOAT:
Double:Code: QB64: [Select]
PRINT "1 decimal place "; PRINT "2 decimal places "; PRINT "3 decimal places "; PRINT "4 decimal places "; PRINT "5 decimal places "; PRINT "6 decimal places "; PRINT "7 decimal places "; PRINT "8 decimal places "; PRINT "9 decimal places "; PRINT "10 decimal places "; '1.2345, 2 => 1.23 integernum# = num# \ 1 decimalnum# = num# / 1 - num# \ 1 n = 10 ^ lenght newdecimalnum# = decimalnum# * n newdecimalnum# = INT(newdecimalnum#) 'or comment this row and rewrite it as newdecimalnum = newdecimalnum \ 1 for rounding outputs. newdecimalnum# = newdecimalnum# / n LNUM# = integernum# + newdecimalnum#
or FLOAT:Code: QB64: [Select]
PRINT "1 decimal place "; PRINT "2 decimal places "; PRINT "3 decimal places "; PRINT "4 decimal places "; PRINT "5 decimal places "; PRINT "6 decimal places "; PRINT "7 decimal places "; PRINT "8 decimal places "; PRINT "9 decimal places "; PRINT "10 decimal places "; '1.2345, 2 => 1.23 integernum## = num## \ 1 decimalnum## = num## / 1 - num## \ 1 n = 10 ^ lenght newdecimalnum## = decimalnum## * n newdecimalnum## = INT(newdecimalnum##) 'or comment this row and rewrite it as newdecimalnum = newdecimalnum \ 1 for rounding outputs. newdecimalnum## = newdecimalnum## / n LNUM## = integernum## + newdecimalnum##
DIM A AS DOUBLE
DIM b AS _FLOAT
A# = 0.12345678901234567890
b## = 0.12345678901234567890
PRINT A#
PRINT b##
That is, both DOUBLE and FLOAT return the same output?Float is broken, you may as well stick to double and forget about Float
Try this:Code: [Select]DIM A AS DOUBLE
DIM b AS _FLOAT
A# = 0.12345678901234567890
b## = 0.12345678901234567890
PRINT A#
PRINT b##
Why?
Float is broken, you may as well stick to double and forget about Float
Oh, I did not know. Broke might imply it did work at one time (and could be fixed).
How broke? is it just is the same as DOUBLE? or worse?
Too Complicated... It's difficult with you, guys, here. You still have some reservations :) Look, BPlus, it doesn't rounding because I didn't mean to. If you look at my source code, the row where this is:
newdecimalnum ## = INT (newdecimalnum ##) 'or comment this row and rewrite it as newdecimalnum = newdecimalnum \ 1 for rounding outputs.
It gives an answer. When you rewrite this, you get a rounded output.
But what surprises me. Neither mine nor Steve's function returns more than a 15-digit decimal. Why? Although a larger decimal number does not seem to be meaningful, it still does the same outputs. That is, both DOUBLE and FLOAT return the same output?
Try this:Code: [Select]DIM A AS DOUBLE
DIM b AS _FLOAT
A# = 0.12345678901234567890
b## = 0.12345678901234567890
PRINT A#
PRINT b##
Why?
DIM A AS DOUBLE
DIM b AS _FLOAT
A# = 0.12345678901234567890
b## = 0.12345678901234567890
PRINT A#
PRINT b##
Oh, I did not know. Broke might imply it did work at one time (and could be fixed).for the most part, the precision is the same as double, in 32-bit the mantissa is more accurate but the range is the same as double, but the range should be much larger
How broke? is it just is the same as DOUBLE? or worse?
The 80-bit floating point format has a range (including subnormals) from approximately 3.65×10−4951 to 1.18×104932. Although log10(264) ≅ 19.266, this format is usually described as giving approximately eighteen significant digits of precision.see https://www.qb64.org/forum/index.php?topic=1957.msg111896#msg111896
DIM a AS _FLOAT, b AS _FLOAT
a = 1
FOR k = 1 TO 175
a = a * k
NEXT
PRINT a
b = LOG(a)
PRINT b
b = a / 10000000000##
PRINT b
PRINT "the factorial of 175 = 1.1244494910857363283041099386422042552 E318"
the division works but not the log function, so I am guessing that the basic 4 arithmetic operators work on Float in QB64 32-bit version but nothing else.
for the most part, the precision is the same as double, in 32-bit the mantissa is more accurate but the range is the same as double, but the range should be much largersee https://www.qb64.org/forum/index.php?topic=1957.msg111896#msg111896
post and onward https://www.qb64.org/forum/index.php?topic=1798.msg110439#msg110439
thread https://www.qb64.org/forum/index.php?topic=1167.msg103597#msg103597
try thisCode: [Select]DIM a AS _FLOAT, b AS _FLOAT
the division works but not the log function, so I am guessing that the basic 4 arithmetic operators work on Float in QB64 32-bit version but nothing else.
a = 1
FOR k = 1 TO 175
a = a * k
NEXT
PRINT a
b = LOG(a)
PRINT b
b = a / 10000000000##
PRINT b
PRINT "the factorial of 175 = 1.1244494910857363283041099386422042552 E318"
In C and related programming languages, long double refers to a floating-point data type that is often more precise than double-precision though the language standard only requires it to be at least as precise as double. As with C's other floating-point types, it may not necessarily map to an IEEE format.
#define __USE_MINGW_ANSI_STDIO 1
// or pass the following directive on the compile command
// -D__USE_MINGW_ANSI_STDIO
#include <stdio.h>
int main()
{
union ldb{
unsigned short m[8];
long double ld;
};
typedef union ldb ldbl;
ldbl x;
x.ld=3.1415926535897932384626433832795L;
printf("%24.19Lf\n",x.ld);
printf("%X",x.m[4]);
printf(" %X",x.m[3]);
printf("%X",x.m[2]);
printf("%X",x.m[1]);
printf("%X",x.m[0]);
return 0;
}
outputf## = 3.1415926535897932384626433832795##
DIM float_pointer AS _MEM
DIM mantissa AS _UNSIGNED _INTEGER64
DIM exponent AS _UNSIGNED INTEGER
float_pointer = _MEM(f##)
mantissa = _MEMGET(float_pointer, float_pointer.OFFSET + 0, _UNSIGNED _INTEGER64)
exponent = _MEMGET(float_pointer, float_pointer.OFFSET + 8, _UNSIGNED INTEGER)
_MEMFREE float_pointer
PRINT HEX$(exponent), HEX$(mantissa)
output