bugfix: floating point precision; added strutils.formatFloat

This commit is contained in:
Araq 2011-01-09 14:52:15 +01:00
commit 064417fc5a
13 changed files with 156 additions and 56 deletions

View file

@ -1,7 +1,7 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2010 Andreas Rumpf
# (c) Copyright 2011 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@ -24,6 +24,17 @@ const
PI* = 3.1415926535897932384626433 ## the circle constant PI (Ludolph's number)
E* = 2.71828182845904523536028747 ## Euler's number
MaxFloat64Precision* = 16 ## maximum number of meaningful digits
## after the decimal point for Nimrod's
## ``float64`` type.
MaxFloat32Precision* = 8 ## maximum number of meaningful digits
## after the decimal point for Nimrod's
## ``float32`` type.
MaxFloatPrecision* = MaxFloat64Precision ## maximum number of
## meaningful digits
## after the decimal point
## for Nimrod's ``float`` type.
type
TFloatClass* = enum ## describes the class a floating point value belongs to.
## This is the type that is returned by `classify`.

View file

@ -935,6 +935,60 @@ proc editDistance*(a, b: string): int {.noSideEffect,
row[p] = x
result = row[e]
#dealloc(row)
# floating point formating:
proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs,
noSideEffect.}
type
TFloatFormat* = enum
ffDefault, ## use the shorter floating point notation
ffDecimal, ## use decimal floating point notation
ffScientific ## use scientific notation (using ``e``) character
proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
precision = 16): string {.noSideEffect,
rtl, extern: "nsu$1".} =
## converts a floating point value `f` to a string.
##
## If ``format == ffDecimal`` then precision is the number of digits to
## be printed after the decimal point.
## If ``format == ffScientific`` then precision is the maximum number
## of significant digits to be printed.
## `precision`'s default value is the maximum number of meaningful digits
## after the decimal point for Nimrod's ``biggestFloat`` type.
const floatFormatToChar: array[TFloatFormat, char] = ['g', 'f', 'e']
var
frmtstr: array[0..5, char]
buf: array[0..80, char]
frmtstr[0] = '%'
frmtstr[1] = '#'
if precision > 0:
frmtstr[2] = '.'
frmtstr[3] = '*'
frmtstr[4] = floatFormatToChar[format]
frmtstr[5] = '\0'
c_sprintf(buf, frmtstr, precision, f)
else:
frmtstr[2] = floatFormatToChar[format]
frmtstr[3] = '\0'
c_sprintf(buf, frmtstr, f)
result = $buf
proc formatFloat*(f: float, format: TFloatFormat = ffDefault,
precision = 16): string {.noSideEffect,
rtl, extern: "nsu$1".} =
## converts a floating point value `f` to a string.
##
## If ``format == ffDecimal`` then precision is the number of digits to
## be printed after the decimal point.
## If ``format == ffScientific`` then precision is the maximum number
## of significant digits to be printed.
## `precision`'s default value is the maximum number of meaningful digits
## after the decimal point for Nimrod's ``float`` type.
result = formatBiggestFloat(f, format, precision)
{.pop.}
@ -944,5 +998,7 @@ when isMainModule:
assert align("1232", 6) == " 1232"
echo wordWrap(""" this is a long text -- muchlongerthan10chars and here
it goes""", 10, false)
assert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001"
assert formatBiggestFloat(0.00000000001, ffScientific, 1) == "1.0e-11"

View file

@ -1,7 +1,7 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2009 Andreas Rumpf
# (c) Copyright 2011 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@ -34,7 +34,8 @@ var
c_stdout {.importc: "stdout", noDecl.}: C_TextFileStar
c_stderr {.importc: "stderr", noDecl.}: C_TextFileStar
var # constants faked as variables:
# constants faked as variables:
var
SIGINT {.importc: "SIGINT", nodecl.}: cint
SIGSEGV {.importc: "SIGSEGV", nodecl.}: cint
SIGABRT {.importc: "SIGABRT", nodecl.}: cint