Page 1 of 1

Floating Point Output?

Posted: Tue Feb 13, 2007 2:09 am
by pcmattman
My OS is going to be a mathematically based system (ie. like a calculator with multitasking and other features). The problem is, I need to know how to output a floating point number to a precision of at least 9 digits.

I've already got a few working functions (abs, pow, sqrt) but I'm hesitant to go any further until I can output a floating point number.

Also, how do I handle shift key-presses on the keyboard handler?

Posted: Tue Feb 13, 2007 2:29 am
by AJ
Hi,

If, by 'output a floating point number' you mean display it on the screen, it sounds like you need a custom version of printf. I have found that for decimal numbers (including floating point), the easiest way is as follows:

Code: Select all

char ltostr(unsigned long lng, char *strbuf)
{
               int tmp=0x00;
               int bufptr=0x00;

	while(lng>=1000000000)
	{
		tmp++;
		lng-=1000000000;
	}
	strbuf[bufptr]=lt_decimal[tmp];
	if (tmp>0)bufptr++;
	tmp=0x00;

	while(lng>=100000000)
	{
		tmp++;
		lng-=100000000;
	}
	strbuf[bufptr]=lt_decimal[tmp];
	if (tmp>0||bufptr>0)bufptr++;
	tmp=0x00;
...
That's just the start of my function, but it's so repetetive you get the idea for the rest. You may be better off using some kind of recursion, simply passing a subtraction operand which you divide by 10 on each pass. The variable 'lt_decimal' is simply a lookup table, but you could equally well add a value to a particular number to get its ascii equivalent. Strbuf is a string buffer passed by the caller.

Of course, for floating point numbers you need to mark the point where there is a decimal point, and do the appropriate for adding a leading zero if you want.

As far as the shift presses are concerned, handle it the same way as the rest of your keyboard driver, except have a flag which you set whenever shift is pressed and clear whenever it is released. Supposing you are using a keyboard map such as:

Code: Select all

char kb_uk[128];
..just extend this to 256 characters long and use the values 128-255 if the shift key is down. Similar things can be said of ctrl and alt.

HTH
Adam[/code]

Posted: Tue Feb 13, 2007 2:50 am
by Solar
You don't need a custom version of printf. Try "%.9f", "%.9e", or "%.9g" for double; "%.9Lf", "%.9Le" or "%.9Lg" for long double, using the library of your choice. Or any higher precision, actually, to the limits of the datatype.

(Unfortunately, PDCLib does not yet support this. "I'm working on it, Jim." 8) )

Posted: Tue Feb 13, 2007 2:57 am
by Solar
AJ wrote:I have found that for decimal numbers (including floating point), the easiest way is as follows:
Erm... AJ? That function is for integers only... floating point is a different ballgame. And for your function, you could simply use sprintf() (or better, snprintf())...

Posted: Tue Feb 13, 2007 3:21 am
by AJ
Hi,

Surely if you are writing a custom libc for your os, you need to write internal decimal->ascii conversion functions for your printf function?

Granted, a better reply would have been to say 'use an existing libc'...

Adam

[edit]Ah - i see another discrepancy. All I want to do at the moment in my code is display int.decimals rather than nEx. Apologies![/i]

Posted: Tue Feb 13, 2007 4:15 am
by Solar
Sorry - my perception is a bit tainted due to PDCLib. I consider kernel work and clib work to be quite seperate. Thus, I assume that people have at least a rudimentary clib in place before setting out to do "serious" kernel work (i.e., bootloader / kernel basics, clib, kernel main), and if they need a certain function, extend the clib instead of doing impromptu custom solutions.

So, when he asks "how to do it in my kernel", I always tend to answer "by using the clib", because I assume he already has one in place.

Posted: Tue Feb 13, 2007 4:21 am
by AJ
Solar wrote:I assume that people have at least a rudimentary clib in place before setting out to do "serious" kernel work
Yes - that would be a more sensible way of doing it. Unfortunately, I tend to leap before I look :)

Posted: Tue Feb 13, 2007 6:04 am
by Solar
How did you manage to grow old enough to use a webbroswer? :shock: :twisted:

Posted: Tue Feb 13, 2007 6:18 am
by Combuster
All you see are his eyes - perhaps there's not even human flesh down there :twisted:


Back to topic: if you dont mind to use assembly you can multiply your float by 10^9 then use FBSTP to write the result as ±xxxxxxxxx.xxxxxxxxx to memory. (= 10-byte packed BCD)

Posted: Tue Feb 13, 2007 3:16 pm
by pcmattman
OK, I've gotten shift to work in the keyboard handler.

Now, about floating point numbers... I want to be able to have a 'ftoa' function (and a 'atof' function) because my OS shell natively supports mathematical operators (+,-,*,/) and also numerous functions (abs,cos,sin,tan etc...). Unfortunately, I don't have a way of putting floats into a string so I can't work with floating point numbers yet...

Posted: Wed Feb 14, 2007 10:55 pm
by Solar
strtod()...

Posted: Thu Feb 15, 2007 12:10 am
by pcmattman
Ok... what about a ftoa? (or are you just going to say dtostr()?)

Posted: Thu Feb 15, 2007 12:50 am
by Solar
Nope, sprintf()... ;)

Posted: Thu Feb 15, 2007 1:33 am
by pcmattman
{vandalised by mod, see below}

Posted: Thu Feb 15, 2007 2:18 am
by Solar
I did it again, hit "Edit" instead of "Quote". ("Edit" of other people's post should come with an additional "Are you sure?" requester...) Apologies to pcmattman for destroying his post.

He stated that he does not have / is right now developing his clib, so he does not have those functions available.

My answer...

----
I'd prefer not to make mistakes because then I have to go back into it's code later.
The advantage of using clib functions: You have to fix them in one place only when you find them to be faulty. ;)
Basically, I'm making the libc then testing it's functions through my OS.
You should test your clib in user space first, it's much easier this way.

As I said, PDCLib does not do floating points yet (but it's pretty high on the to-do list).

You can find basic functionality for sprintf() and strtod() in Paul Edward's PDPCLIB. Note that those functions aren't really standard compliant, so don't use the standard as documentation reference, but look at the functions themselves to find their limits. (The strtod() found there for example does not skip leading whitespace as the standard advertises, and does not cover all possible float notations.)