Ranter
Join devRant
Do all the things like
++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatar
Sign Up
Pipeless API
From the creators of devRant, Pipeless lets you power real-time personalized recommendations and activity feeds using a simple API
Learn More
Comments
-
This is what happens when you pay developer by line of code...
(It is the only reason I can see to produce this abortion of a thought process) -
awelxtr2007y@hexc I was thinking of returning the integer part of the logarithm but I guess yours is a more understandable solution
-
@gnulinuxer4fun I feel like the log 10 trick is faster. Or at least better style, if you made it a C++ constexpr it be best of both
-
Root825087yA) Repost.
B) Most optional solution. (Benchmark it.)
C) Best approach for low-resource scenarios, e.g. embedded systems
D) Ugly, but considering the above: swallow your pride. -
LLAMS37487yto be honest the thing that triggers me about this code is the name of the function: “numLen”
Are we not allowed to use full words? -
fico452197yLooks like a code we used to make for the exam during the 1st year of college. Hell we knew that lenght function existed.
-
You guys need to appreciate more.
Don't read the code. Just look at it as an artistic point of view.
Owo! What a nice piece of artwork!
What I see is 2 mountain inside 3 railroad track. -
fico452197y@shahriyer I know I felt like a hugeass smart OP developer when writing 20 else if lines of code.
"MOM, I'M CODING!" -
Log10 trick lol as if a lookup table andor the calculation of log is faster than sub, followed by some jnz.
If the numbers had the 10eN style, it'd be pretty and fast. -
The program will also crash or misbehave if it gets a number higher than in the last if-statement or a negative one. 🤣
I didn't even know that common C++-Compilers allow such methods to compile. -
justmove7367y@Root I still would have never done this on an 8bit microcontroller in C. And that thing had low resources.
-
WHYYY
and this is the 2nd or 3rd time I saw someone here come across exactly this kind of code D; -
human0615947y@corscheid maybe because we all share things we find funny.. and not everyone have seen what have been shared !
-
Root825087y@eeee Consider the assembly a compiler would generate for every approach:
Raw comparisons:
The raw checks are only a few instructions per tier. Given the presented code as-is, it would be two compares and two jumps per failed check, plus a move/load and a ret upon success (may differ by compiler and architecture). Also, any number that falls in an earlier block will resolve faster, meaning the theoretical median execution would be around 38 instructions ((18/2)*4+2). The number of clocks should closely mirror ther instruction count; I'm unsure how many clocks a 4-byte comparison takes, however.
Also, this is before compiler optimizations: All of the first comparisons (save the initial >=0) should simply go away, leaving one compare and one jump per failed check. That lowers the median to 22 instructions ((18/2)*2+2+2). Very inexpensive!
(The only thing I'm wondering about here is memory paging for the constants; they should be in cache, though.)
Log10:
I don't actually know how expensive a log10 implementation would be as I've never needed to use/write one in assembly before, but given the math required, I believe it would be consistently more expensive than the median above.
Lookup table:
A log10 lookup table for such a large value range would need to do basically the same checks the presented code is already doing prior to actually looking up the data. It would also have the added overhead of calling it, so unless the program is only ever using a smaller set of numbers, this approach would not help.
Casting:
String casting? Are you kidding?
Try converting 0x100000 to "32" and returning the byte count in around 8 instructions. Go on. Longer strings would have better efficiency, but this approach could never hope to compete.
-----
So, save possibly a log10 implementation I'm not aware of, the presented code is definitely the better approach. (Even if it is ugly.) -
// @Root
long long copyThisFrigg(long long x) {
//{
if (x<0L) throw FriggYourselfExeption;
if (x==0L) return 1;//should be 0, drives me nuts, but whatever
int len=1;
for( ; x<10L;
x=x%10,
len++) ;
return len;
} -
Just
Log10 sounds very good but it's some error prone in the float->int casting part, and it's pretty more expensive. -
Root825087y@hch11 😅
I knew what you meant, actually.
I wanted to write up an implementation and compare the assembly produced between that and (optimized) hardcoded compares.
I started to, but got called away on two work emergencies today and just haven't had time. -
aritzh7537y@Root just been noticing you like assembly. Do you know Compiler Explorer, by any chance?
https://godbolt.org
It lets you see the assembly output of a C/C++ and more, and compare different optimization flags, compilers, and even versions 😉. -
cyclic3406yIf you put it the other way up, you can remove the second condition from all of the ifs
-
cyclic3406y@electrineer each of the if conditions check the condition below it isn't true. By reversing their order, you can make that condition redundant, allowing you to remove it and half the number of comparisons you need to make, giving a ~2x speed increase with no negative impacts
-
@cyclic3
1) you can achieve the same whether you go from low to high or high to low
2) don't estimate speed increases like that
Boy oh boy .... 🤭 .. look what I came across !!
rant