In 1967, I modified some code that had been written to convert floating
point numbers to a string. The code had been written by a floating-point
expert. On the whole, it was unintelligible, because wired into it was
every bizarre detail of the /360 floating point, including idiosyncrasies
related to its hexadecimal normalization and roundoff/truncation behavior.
The author claimed correctness to 1LSB on any conversion. The code was
several thousand lines of /360 assembly code. In 1969, I wrote a floating
point conversion library for the PDP-10 arcitecture. It was many hundreds
of lines of C-level code (although the language was not C). When I looked
at the Microsoft CRT sources, there is a kernel call to do the conversion.
So I can believe easily that no effort was put into making the kernel CRT
support these.
Using a global buffer ranks right up there in The List Of Really Bad
Ideas. It is a horrible thing to do in an app, and an insanely dangerous
thing to do in the kernel. Note to the OP: unless you are an experienced
driver writer who understands ALL of the consequences of a global
variable, DON’T DO IT!!! Something about angels treading comes to mind
here…
Get out of te habit of using this idiom. It is dangerous. There is truly
no valid excuse in this case for using such a poor programming technique.
And, of course, there is the question about why you are doing floating
point arithmetic in the kernel at all. Like most rules, there are rare
and exotic reasons for doing so, but you must have one of these situations
before you consider it. Note also that there are convenient tricks for
converting the floating point to a pair of integers which can be printed
out as %d.%0nd where n is the number of decimal places you need.
double d;
…compute value in d
int before = (int) d;
int after = abs( (int)(d * 1000) % 1000);
DebugPrint("%d.%03d, before, after);
This will be “close enough” because it does weird things near the limits,
but for reasonable ranges of data it is good enough. Note that it does
not do rounding; that’s left as an Exercise For The Reader. However,
proper rounding is one of those tricky things in floating point; every
piece of code I’ve seen uses weird constants that are conscious of how the
FPU works. In some cases, I’ve seen them in octal or hex because the
author discovered that the assembler/compiler, in processing the costant
written in floating point, would translate it according to its opinion of
what the translation ought to be. In one infamous case, the IBM FORTRAN-G
compiler converted source constants differently than the FORTRAN-H
compiler, and for efficiency, their runtimes used a different algorithm
that was not as precise but which ran faster (at least, both runtimes used
the same algorithm). For debugging purposes, such precision is usually
unnecessary, which is why I didn’t bother with it.
So, unless you are doing some “filter” in an audio or video cascade, you
should avoid floating point as much as possible. It is truly very rare to
need it in ordinary drivers.
Don’t think of drivers as some kind of app that happens to run in kernel
space. They are their own world, and you cannot lightly transfer app
programming habits into the kernel. And some, like the use of a global
buffer, should be abandoned entirely. In the app world, multithreading
will kill you; in the kernel, multithreading is so fundamental that you
have to assume it is always there. Global variables which are used for
gratuitous communication with subroutines are a very bad habit to have in
a multithreaded universe. A good general rule for utility conversion
routines is that they use no values except their parameters and locals.
There are exceptions, of course, but your situation is absolutely /not/
one of these exceptions!
joe
maomao2722 wrote:
>
> vspfunc is putting the result in global “buffer” , my vspfunc is used
> in another placer
> so this is why I’m not just call vsprintf ,Now I modified my code as
> bellow, but it has
> the same problem , is it not available to print the float number in
> Windows Kernel ?
Correct. That is the fundamental problem. The kernel version of printf
simply does not support the floating point specifiers (%e %f %g).
And those are not trivial to implement…
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer