Code: Select all

```
#include once "crt/math.bi"
Dim num As Double
Dim roundedNum As Integer
Input "Enter a number to round: ", num
roundedNum = Round(num)
Print "The rounded number is: "; roundedNum
sleep
```

Hi hhr I got this from deepai.

Code: Select all

```
#include once "crt/math.bi"
Dim num As Double
Dim roundedNum As Integer
Input "Enter a number to round: ", num
roundedNum = Round(num)
Print "The rounded number is: "; roundedNum
sleep
```

Last edited by neil on Feb 05, 2024 0:29, edited 1 time in total.

Hi neil,

there is an instruction that one doesn't know (round). We definitely have to tell the FreeBASIC developers about this.

there is an instruction that one doesn't know (round). We definitely have to tell the FreeBASIC developers about this.

Maybe this is better?

#include once "crt/math.bi"

#include once "crt/math.bi"

Yes very good. We shouldn't put too much strain on the developers.

Hi hhr Here's another way to round numbers.

Code: Select all

```
Dim number As Single
Dim integerPart As Integer
Dim decimalPart As Single
Input "Enter a Number: ", number
integerPart = Int(number)
decimalPart = number - integerPart
If decimalPart >= 0.5 Then
integerPart = integerPart + 1
End If
Print "Rounded number: "; integerPart
sleep
```

Here's PI to 2 decimal places.

Code: Select all

```
Function RoundNumber(number As Double, decimalPlaces As Integer) As Double
Dim multiplier As Double
multiplier = 10 ^ decimalPlaces
RoundNumber = Int(number * multiplier + 0.5) / multiplier
End Function
Dim num As Double
Dim roundedNum As Double
Dim decimalPlaces As Integer
num = 3.14159
decimalPlaces = 2
roundedNum = RoundNumber(num, decimalPlaces)
Print "Original number: "; num
Print "Rounded number: "; roundedNum
sleep
```

Here's another example. This prints PI to 5 decimal places.

Code: Select all

```
Function RoundDecimal(num As Double, decimals As Integer) As Double
Dim temp As Double
temp = 10 ^ decimals
RoundDecimal = Int(num * temp + 0.5) / temp
End Function
Dim number As Double
number = 3.14159265
Print RoundDecimal(number, 5) ' 5 decimal places
sleep
```

A counter-example takes us back to the beginning.

You cannot use double because double works internally with a binary representation.

Errors occur when converting from decimal to binary and vice versa.

That's why I think you have to work consistently with strings and/or Ulongint.

Perhaps you have another idea.

You cannot use double because double works internally with a binary representation.

Errors occur when converting from decimal to binary and vice versa.

That's why I think you have to work consistently with strings and/or Ulongint.

Perhaps you have another idea.

Code: Select all

```
Function RoundNumber(number As Double, decimalPlaces As Integer) As Double
Dim multiplier As Double
multiplier = 10 ^ decimalPlaces
RoundNumber = Int(number * multiplier + 0.5) / multiplier
End Function
Dim num As Double
Dim roundedNum As Double
Dim decimalPlaces As Integer
'=======================================
num = 95.225000195
decimalPlaces = 4
roundedNum = RoundNumber(num, decimalPlaces)
Print "Original number: "; num,decimalPlaces
Print "Rounded number: "; roundedNum
print string(35,"-")
'=======================================
num = 836.87938866205
decimalPlaces = 5
roundedNum = RoundNumber(num, decimalPlaces)
Print "Original number: "; num,decimalPlaces
Print "Rounded number: "; roundedNum
print string(35,"-")
'=======================================
num = 0.087898873956
decimalPlaces = 4
roundedNum = RoundNumber(num, decimalPlaces)
Print "Original number: "; num,decimalPlaces
Print "Rounded number: "; roundedNum
print string(35,"-")
'=======================================
sleep
```

Hi hhr I only tested it with PI. Have you looked into the Round function?

With the Round function, one cannot specify the decimal places.

I have also noticed that all these functions have errors.

The Format function has the worst error.

As I said, I can only avoid the errors if I avoid Double.

The functions I introduced here at the beginning (RoundDouble, RoundDouble3) work with Strings and/or Ulongint.

They are not complete, there is still a lot to do, but they work without errors.

I am interested to know if anyone has any other ideas.

I have also noticed that all these functions have errors.

The Format function has the worst error.

As I said, I can only avoid the errors if I avoid Double.

The functions I introduced here at the beginning (RoundDouble, RoundDouble3) work with Strings and/or Ulongint.

They are not complete, there is still a lot to do, but they work without errors.

I am interested to know if anyone has any other ideas.

Hi hhr look at this.

Code: Select all

```
#include "crt/stdio.bi"
Dim AS Double num
num = 95.225000195
printf(!"original number %.9f\n\n",num)
printf(!"round to 1 place %.1f\n",num)
printf(!"round to 2 places %.2f\n",num)
printf(!"round to 3 places %.3f\n",num)
printf(!"round to 4 places %.4f\n",num)
printf(!"round to 5 places %.5f\n",num)
printf(!"round to 6 places %.6f\n",num)
printf(!"round to 7 places %.7f\n",num)
printf(!"round to 8 places %.8f\n",num)
printf(!"round to 9 places %.9f\n",num)
sleep
```

Here is an example where printf and sprintf make an error.

But you have to test with as many examples as possible, which is only possible with a program.

But you have to test with as many examples as possible, which is only possible with a program.

Code: Select all

```
#Include "crt.bi" ' is needed for sprintf,printf
Dim As Double n
Dim As Integer decimals
Dim As Zstring*20 zs
n = 462.445
decimals = 2
Print "Number: ";n
Print "printf: ";
printf("%.*f",decimals,n)
Print
sprintf(zs,"%.*f",decimals,n)
Print "sprintf: ";zs
Print "Print Using: ";
Print Using "###.##";n
Sleep
```

With this example I am trying to test printf.

I hope that the numbers used for testing are put together reasonably.

I hope that the numbers used for testing are put together reasonably.

Code: Select all

```
#Include "crt.bi"
Function printfToString(number As Double, decimals As Integer) As String
Dim As Long i,row,column
Dim As String s,exponent
s = Str(number) 'Copy the number as string
If Instr(s,"e") Then 'Separate mantissa and exponent
exponent = Right(s,Len(s)-Instr(s,"e")+1)
s = Rtrim(s,exponent)
End If
'Save row and column, write to console:
column = Pos
row = Csrlin
printf("%.*f",decimals,number)
'Read from console:
s = Space(0)
For i = 0 To 20
s += Chr(Screen(row,column+i))
Next
'Delete written text in console:
Locate row,column
Print Space(20); 'Note the semicolon
'Set the cursor to original position:
Locate row,column
'Finalize string:
s = Rtrim(s)
If Instr(s,".") > 0 Then s = Rtrim(s,"0")
s = Rtrim(s,".")
s = s & exponent
'A positive number should be preceded by a space:
If (Left(s,1) <> "-") Then s = Space(1) & s
Return s
End Function
Function RoundDouble(number As Double, decimals As Integer) As String
Dim As String s,sign,exponent
Dim As Integer dp
Dim As Byte i,carry
s = Str(number) 'Copy the number as string
If Left(s,1) = "-" Then 'Remove the sign
sign = "-"
s = Ltrim(s,"-")
Else
sign = Space(1)
End If
If Instr(s,"e") Then 'Separate mantissa and exponent
exponent = Right(s,Len(s)-Instr(s,"e")+1)
s = Rtrim(s,exponent)
End If
dp = Instr(s,".") 'decimal point
If dp > 0 Then 'If decimal point present
i = dp + Abs(decimals) 'Determine the first carry
If s[i] >= 53 Then carry = 1 'Chr(53)="5"
s = Left(s,i) ' Remove omitted digits
While (carry = 1)
i -= 1
If i = -1 Then s = "1" & s : Exit While 'The carry has run through all the digits, can happen with many nines.
If Chr(s[i]) = "." Then i -= 1 'Skip the decimal point
If s[i] < 57 Then 'Chr(57)="9"
s[i] += 1
carry = 0
Else
s[i] = 48 'Chr(48)="0", Carry over remains 1
End If
Wend
s = Rtrim(s,"0")
s = Rtrim(s,".")
End If
s = sign & s & exponent
Return s
End Function
'testing:
Randomize
Dim As Double n,nsign
Dim As Integer decimals
Dim As String s1,s2
Do
'Make up the number:
n = Fix(Rnd*1000000)/1000
nsign = Iif(Rnd<0.5,-1,1)
n = nsign*n
decimals = Int(Rnd*4)
'Printout:
s1 = RoundDouble(n,decimals)
s2 = printfToString(n,decimals)
Print "Number: ";Space(8);n;Tab(50);"decimals: ";decimals
Print "RoundDouble: ";s1
Print "printfToString: ";s2
If s1<>s2 Then Print "Different, any key to continue...":Sleep
Print String(30,"-")
'Getkey
Loop
```

Hi hhr Try testing this.

Code: Select all

```
Dim a as double
a = 836.87938866205
Print "original number ";a
PRINT USING "###.#"; a
PRINT USING "###.##"; a
PRINT USING "###.###"; a
PRINT USING "###.####"; a
PRINT USING "###.#####"; a
PRINT USING "###.######"; a
PRINT USING "###.#######"; a
PRINT USING "###.########"; a
PRINT USING "###.#########"; a
PRINT USING "###.##########"; a
PRINT USING "###.###########"; a
sleep
```

I just read a trick for rounding numbers with printf. The trick is to add a 5 to the number, in the decimal place just past the digits you want to round to. For example, printf("%0.2f", 0.635 + 0.005). that guarantees it will round even as it truncates.