mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Guilherme Giácomo Simões" <trintaeoitogc@gmail.com>
To: linux-kernel@vger.kernel.org
Subject: new library
Date: Thu, 11 Jan 2024 21:48:46 -0300	[thread overview]
Message-ID: <5AFF5BF9-BD11-4A60-BD42-7EC516164D41@gmail.com> (raw)

 Hi,

im a software developer and i have been studying and writing device drivers on an amateur basis.

I discovered that the float points are not easy to work in kernel land, for an obvious reason: Each CPU has a its owner way dealing with float points in FPU,

and somes CPUs don't have an FPU.

Although, with the kernel_fpu_begin/end, I can do arithmetic with float points....

But i wanted to show this in printk(), and unless im very mistaken this is not possible. What i can do is show a float point as an int number.

For ex: 12.34, changed to 1234. In dmesg output: [123432] 1234.


This is make never implemented, because probably dealing with floating points at the kernel land is extremely rare.

But, in my kernel fork I writed a library to change an integer number, to string with float point.

For ex: 1234 -> "12.34", and i show this in dmesg output: [09876] 12.34


I really don't know if this is useful, but here it is my initial sugestion is


include/linux/int2fpstr.h ++++++++


+ #ifndef _LINUX_INT2FPSTR_H
+ #define _LINUX_INT2FPSTR_H
+
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
+
+ inline __kernel_size_t size_alloc(int number)
+ {
+     const int neg =  number < 0;
+     if(neg) number *= -1;
+
+     int ret = neg ? 2 : 1;
+     for(;
+         number;
+         number /= 10, ret++
+     );
+
+     return ret;
+ }
+
+ inline void int2fpstr(int number,
+         const int decimal_places, char* dest)
+ {
+     if(!number)    {
+         strncpy(dest, "0", 1);
+         return;
+     }
+
+     const __kernel_size_t size_alloc_n = size_alloc(number);
+     char* buffer = kmalloc(size_alloc_n, GFP_KERNEL);
+
+     int buf_index = size_alloc_n;
+     *(buffer + buf_index) = '\0';
+
+     int c_dec_places = 0;
+     int point_include = decimal_places < 1;
+
+     int neg = number < 0;
+     if(neg)
+         number *= -1;
+
+     for (; number && buf_index;
+         --buf_index, number /= 10)
+     {
+         c_dec_places++;
+         if (!point_include
+             && c_dec_places > decimal_places)
+         {
+             *(buffer + buf_index--) = '.';
+             point_include = 1;
+         }
+
+         *(buffer + buf_index) = "0123456789"[number % 10];
+     }
+
+     if(neg)
+         *(buffer + buf_index--) = '-';
+
+     strncpy(dest, &buffer[buf_index+1], size_alloc_n);
+ }
+
+ #endif



so, i create a unitest to library:

lib/int2fpstr_kunit.c ++++++

+ #include <kunit/test.h>
+ #include <linux/slab.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+
+ #include <linux/int2fpstr.h>
+
+ static void should_return_2345_without_errors(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(2345), GFP_KERNEL);
+     int2fpstr(2345, 2, dest);
+     int ret = strncmp(dest, "23.45", 5);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_2_without_errors_and_float_point(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(2), GFP_KERNEL);
+     int2fpstr(2, 0, dest);
+     int ret = strncmp(dest, "2", 1);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_0_without_errors(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(1), GFP_KERNEL);
+     int2fpstr(0, 0, dest);
+     int ret = strncmp(dest, "0", 1);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_12_without_errors_and_float_point(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(12), GFP_KERNEL);
+     int2fpstr(12, 0, dest);
+     int ret = strncmp(dest, "12", 2);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_12_without_errors(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(12) + 1, GFP_KERNEL);
+     int2fpstr(-12, 0, dest);
+     int ret = strncmp(dest, "-12", 3);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_125_without_errors(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(125), GFP_KERNEL);
+     int2fpstr(-125, 1, dest);
+     int ret = strncmp(dest, "-12.5", 5);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static struct kunit_case int_to_fp_str_test_case[] = {
+     KUNIT_CASE(should_return_12_without_errors_and_float_point),
+     KUNIT_CASE(should_return_0_without_errors),
+     KUNIT_CASE(should_return_2_without_errors_and_float_point),
+     KUNIT_CASE(should_return_2345_without_errors),
+     KUNIT_CASE(should_return_12_without_errors),
+     KUNIT_CASE(should_return_125_without_errors),
+     { /* sentinel */ }
+ };
+
+ static struct kunit_suite int_to_fp_str_test = {
+     .name = "int2fpstr",
+     .test_cases = int_to_fp_str_test_case
+ };
+
+ kunit_test_suite(int_to_fp_str_test);
+
+ MODULE_AUTHOR("Guilherme Giacomo Simoes <trintaeoitogc@gmail.com>");
+ MODULE_LICENSE("GPL");


This library can help the drivers writers, and (perhaps and very rarely) the subsystems writers. 


             reply	other threads:[~2024-01-12  0:49 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-12  0:48 Guilherme Giácomo Simões [this message]
2024-01-12  1:06 ` Al Viro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5AFF5BF9-BD11-4A60-BD42-7EC516164D41@gmail.com \
    --to=trintaeoitogc@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®