Floating Point Output?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Floating Point Output?

Post 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?
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post 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]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post 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) )
Every good solution is obvious once you've found it.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post 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())...
Every good solution is obvious once you've found it.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post 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]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post 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.
Every good solution is obvious once you've found it.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post 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 :)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

How did you manage to grow old enough to use a webbroswer? :shock: :twisted:
Every good solution is obvious once you've found it.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post 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)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post 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...
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

strtod()...
Every good solution is obvious once you've found it.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Ok... what about a ftoa? (or are you just going to say dtostr()?)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Nope, sprintf()... ;)
Every good solution is obvious once you've found it.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

{vandalised by mod, see below}
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post 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.)
Every good solution is obvious once you've found it.
Post Reply