Finding the next multiple of eight (implementing tabs)

Programming, for all ages and all languages.
Post Reply
osdf_1
Posts: 20
Joined: Sun Nov 25, 2007 7:55 pm

Finding the next multiple of eight (implementing tabs)

Post by osdf_1 »

I was developing my keyboard driver when I came across tabs. A tab should move the cursor to the next multiple of eight in a line. So I looked up tab implementations in the Bran's KDT source and found this:

Code: Select all

cursorX = (cursorX + 8) & ~(8 - 1);
(cursorX is the current x position of the cursor)
It feels wrong to copy code I don't understand to my kernel, so can someone explain this code to me?

Thanks
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Re: Finding the next multiple of eight (implementing tabs)

Post by Alboin »

Hi,

Code: Select all

cursorX = (cursorX + 8) & ~(8 - 1);
The part probably confusing you is the '~(8 - 1)'. (8-1) is 7. 7 in binary is 111. The '~' switches all the bits in the data: all the 1's become 0's and the 0's become 1's. This effectively creates a mask that masks the lower three bits of whatever data it is AND'd against. In this case, it is used to mask (cursorX + 8 ) So, if cursorX was 13, and one wanted to find the next tab, it would be:

(13 + 8 ) & ~7
21 & 0xfffffff8
16

The next tab, is thus 16. This works, because you're simply dropping the bits that holds the offset within your specific alignment. As another example, if you had a virtual address, and wanted to find its base page, all you would have to do is:

v_addr & ~(4096 - 1)

Here, you're dropping the last 12 bits, which holds the offset within a 0x1000 region.

Say, in decimal, that you wanted to find out how many thousands were in the number 9058. Obviously, there are 9. How did you do that? You just got rid of the 58. ;)

Hope that helps,
Alboin
C8H10N4O2 | #446691 | Trust the nodes.
osdf_1
Posts: 20
Joined: Sun Nov 25, 2007 7:55 pm

Re: Finding the next multiple of eight (implementing tabs)

Post by osdf_1 »

That really helped, thanks.
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:

Re: Finding the next multiple of eight (implementing tabs)

Post by Combuster »

For completeness sake, I want to add that this trick only works for alignments that are powers of two (indents of 5 or 10 won't work that way).
"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 ]
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: Finding the next multiple of eight (implementing tabs)

Post by Korona »

If your tab width is not a power of 2 you can use the following snippet:

Code: Select all

uint tabwidth = 3;
positionX += tabwidth - positionX % tabwidth;
If tabwidth is a power of two the compiler should be able to replace the modulo operation by an and operation.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
Post Reply