Implementing absolute value function in cproblem with printing function return valueAbsolute address of a function in Microchip XC16Use of free() in PIC Microcontroller ProgrammingThe 4-wire resistive touch is connected to the ADC's input but it doesn't give correct valueXC32 optimizes vaiable used for register readingFunction not working probably like expected, using TM4C123 MCUPLC - get absolute value of number when the CPU has no “ABS” instructionDelay function for a STM32L152ADXL343 data readHow do you calculate average absolute value of a sum of sin functions with different amplitudes and frequencies?

How did Einstein know the speed of light was constant?

What's the big deal about the Nazgûl losing their horses?

Implementing absolute value function in c

Do intermediate subdomains need to exist?

How serious is plagiarism in a master’s thesis?

Why did C++11 make std::string::data() add a null terminating character?

Does a multiclassed wizard start with a spellbook?

Platform Event Design when Subscribers are Apex Triggers

Taking advantage when the HR forgets to communicate the rules

Should I increase my 401(k) contributions, or increase my mortgage payments

Machine Learning Golf: Multiplication

Motorcyle Chain needs to be cleaned every time you lube it?

What are the differences of checking a self-signed certificate vs ignore it?

Why did moving the mouse cursor cause Windows 95 to run more quickly?

Why does the Batman "crack his knuckles" in "Batman: Arkham Origins"?

How to calculate a conditional PDF in mathematica?

How can solar sailed ships be protected from space debris?

Do the 26 richest billionaires own as much wealth as the poorest 3.8 billion people?

How do both sides know the MTU

Is it possible to spoof an IP address to an exact number?

Speeding up thousands of string parses

Can 4 Joy cons connect to the same Switch?

Who pays for increased security measures on flights to the US?

Why did the "Orks" never develop better firearms than Firelances and Handcannons?



Implementing absolute value function in c


problem with printing function return valueAbsolute address of a function in Microchip XC16Use of free() in PIC Microcontroller ProgrammingThe 4-wire resistive touch is connected to the ADC's input but it doesn't give correct valueXC32 optimizes vaiable used for register readingFunction not working probably like expected, using TM4C123 MCUPLC - get absolute value of number when the CPU has no “ABS” instructionDelay function for a STM32L152ADXL343 data readHow do you calculate average absolute value of a sum of sin functions with different amplitudes and frequencies?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








6












$begingroup$


is implementing a function to find the absolute value like this:



uint16_t absolute_value(int16_t n)

int16_t mask = n >> 15;
return((n+mask)^mask);



Any quicker than just doing a simple multiply by -1 if less than 0? this code is on a microprocessor where speed is everything.










share|improve this question









$endgroup$







  • 1




    $begingroup$
    Multiplying by -1 is just bitwise inversion and adding 1. Any decent compiler will know this and generate this code instead of a multiply. Your code might be faster (depending on architecture) because it doesn't branch.
    $endgroup$
    – The Photon
    10 hours ago







  • 2




    $begingroup$
    Probably the most bang for the buck is making it a macro and not a function call, since the call overhead is bigger than the work you do in the function. That's what stdlib.h will typically take care off as well.
    $endgroup$
    – Hilmar
    9 hours ago






  • 4




    $begingroup$
    @Hilmar Preprocessor macros are evil. Much better would be an inline function, so the compiler can do type checking.
    $endgroup$
    – Elliot Alderson
    9 hours ago

















6












$begingroup$


is implementing a function to find the absolute value like this:



uint16_t absolute_value(int16_t n)

int16_t mask = n >> 15;
return((n+mask)^mask);



Any quicker than just doing a simple multiply by -1 if less than 0? this code is on a microprocessor where speed is everything.










share|improve this question









$endgroup$







  • 1




    $begingroup$
    Multiplying by -1 is just bitwise inversion and adding 1. Any decent compiler will know this and generate this code instead of a multiply. Your code might be faster (depending on architecture) because it doesn't branch.
    $endgroup$
    – The Photon
    10 hours ago







  • 2




    $begingroup$
    Probably the most bang for the buck is making it a macro and not a function call, since the call overhead is bigger than the work you do in the function. That's what stdlib.h will typically take care off as well.
    $endgroup$
    – Hilmar
    9 hours ago






  • 4




    $begingroup$
    @Hilmar Preprocessor macros are evil. Much better would be an inline function, so the compiler can do type checking.
    $endgroup$
    – Elliot Alderson
    9 hours ago













6












6








6


1



$begingroup$


is implementing a function to find the absolute value like this:



uint16_t absolute_value(int16_t n)

int16_t mask = n >> 15;
return((n+mask)^mask);



Any quicker than just doing a simple multiply by -1 if less than 0? this code is on a microprocessor where speed is everything.










share|improve this question









$endgroup$




is implementing a function to find the absolute value like this:



uint16_t absolute_value(int16_t n)

int16_t mask = n >> 15;
return((n+mask)^mask);



Any quicker than just doing a simple multiply by -1 if less than 0? this code is on a microprocessor where speed is everything.







microcontroller c math






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 10 hours ago









user9964422user9964422

433 bronze badges




433 bronze badges







  • 1




    $begingroup$
    Multiplying by -1 is just bitwise inversion and adding 1. Any decent compiler will know this and generate this code instead of a multiply. Your code might be faster (depending on architecture) because it doesn't branch.
    $endgroup$
    – The Photon
    10 hours ago







  • 2




    $begingroup$
    Probably the most bang for the buck is making it a macro and not a function call, since the call overhead is bigger than the work you do in the function. That's what stdlib.h will typically take care off as well.
    $endgroup$
    – Hilmar
    9 hours ago






  • 4




    $begingroup$
    @Hilmar Preprocessor macros are evil. Much better would be an inline function, so the compiler can do type checking.
    $endgroup$
    – Elliot Alderson
    9 hours ago












  • 1




    $begingroup$
    Multiplying by -1 is just bitwise inversion and adding 1. Any decent compiler will know this and generate this code instead of a multiply. Your code might be faster (depending on architecture) because it doesn't branch.
    $endgroup$
    – The Photon
    10 hours ago







  • 2




    $begingroup$
    Probably the most bang for the buck is making it a macro and not a function call, since the call overhead is bigger than the work you do in the function. That's what stdlib.h will typically take care off as well.
    $endgroup$
    – Hilmar
    9 hours ago






  • 4




    $begingroup$
    @Hilmar Preprocessor macros are evil. Much better would be an inline function, so the compiler can do type checking.
    $endgroup$
    – Elliot Alderson
    9 hours ago







1




1




$begingroup$
Multiplying by -1 is just bitwise inversion and adding 1. Any decent compiler will know this and generate this code instead of a multiply. Your code might be faster (depending on architecture) because it doesn't branch.
$endgroup$
– The Photon
10 hours ago





$begingroup$
Multiplying by -1 is just bitwise inversion and adding 1. Any decent compiler will know this and generate this code instead of a multiply. Your code might be faster (depending on architecture) because it doesn't branch.
$endgroup$
– The Photon
10 hours ago





2




2




$begingroup$
Probably the most bang for the buck is making it a macro and not a function call, since the call overhead is bigger than the work you do in the function. That's what stdlib.h will typically take care off as well.
$endgroup$
– Hilmar
9 hours ago




$begingroup$
Probably the most bang for the buck is making it a macro and not a function call, since the call overhead is bigger than the work you do in the function. That's what stdlib.h will typically take care off as well.
$endgroup$
– Hilmar
9 hours ago




4




4




$begingroup$
@Hilmar Preprocessor macros are evil. Much better would be an inline function, so the compiler can do type checking.
$endgroup$
– Elliot Alderson
9 hours ago




$begingroup$
@Hilmar Preprocessor macros are evil. Much better would be an inline function, so the compiler can do type checking.
$endgroup$
– Elliot Alderson
9 hours ago










3 Answers
3






active

oldest

votes


















8












$begingroup$

The standard C library is providing the optimized solutions for many problems with considerations based on the architecture, compiler in use and others. The abs() function defined in stdlib.h is one of these, and it is used for your purpose exactly. To emphasize the point, here is ARM compiler result when using abs vs a version of a homebrew abs: https://arm.godbolt.org/z/aO7t1n



Paste:



#include <stdio.h>
#include <stdlib.h>

int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", abs(x));



results in



main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L4
bl printf
mov r0, #0
pop r4, pc
.L4:
.word .LC0
.LC0:
.ascii "%d1200"


And



#include <stdio.h>
#include <stdlib.h>

int my_abs(int x)

return x < 0 ? -x : x;


int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", my_abs(x));



results in



my_abs:
cmp r0, #0
rsblt r0, r0, #0
bx lr
main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L5
bl printf
mov r0, #0
pop r4, pc
.L5:
.word .LC0
.LC0:
.ascii "%d1200"


Notice that the main code is almost identical in both codes as the my_abs got inlined, and it's implementation is the same as the standard one.






share|improve this answer











$endgroup$












  • $begingroup$
    Your final comment is perfect. Since the result is know at compile time, the codes do not actually calculate the abs.
    $endgroup$
    – vangelo
    9 hours ago











  • $begingroup$
    @vangelo Are you saying I have cheated? :) Well, let me get another example
    $endgroup$
    – Eugene Sh.
    9 hours ago










  • $begingroup$
    Of course not! I'm just pointing out that both codes already show the result in the assembly. :)
    $endgroup$
    – vangelo
    9 hours ago







  • 2




    $begingroup$
    @vangelo OK, then I will leave it to the reader :) Which is by the way another thing. If my_abs was defined in a separate translation unit (source file), the compiler would not know what it does and won't be able to optimize it to a compile-time result. But with standard abs it always knows it.
    $endgroup$
    – Eugene Sh.
    9 hours ago











  • $begingroup$
    Oh well. Here it is: arm.godbolt.org/z/AIzLre One can notice there is no function call at all when using abs.
    $endgroup$
    – Eugene Sh.
    9 hours ago


















4












$begingroup$

The speed of a given solution will depend greatly on the architecture, but in C I would say



return (n > 0 ? n : -n);


and let the compiler figure out the best solution.



EDIT: @jonk points out correctly that this will fail for the most-negative possible value of n, assuming that two's-complement arithmetic is used.



Yes, my solution has a conditional branch, but yours has an arithmetic operator and two bitwise operators. Can your microcontroller shift 15 places in a single clock?






share|improve this answer











$endgroup$








  • 2




    $begingroup$
    This is basically just to agree. If a fully portable solution is desirable, do it simple, as you suggested. If the best/shortest/fastest option is needed, it will depend on your processor/compiler and it is very likely that the standard (or non-standard) library will provide the best code.
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @vangelo Just one minor point...I think that the functions in stdlib are defined for int rather than int16_t or uint16_t. The size of an int may be 32 bits, which could influence speed. But you are correct that if an appropriate library function is available it is best to use it.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    I agree. This is why I also mentioned non-standard. It is not uncommon that "extensions" are available and in fact quite common with micro-controllers.
    $endgroup$
    – vangelo
    9 hours ago



















3












$begingroup$

There are a lot of subtle details in using C. Given your comment about speed, it is probably worth your time to try out various options and see which produces better assembly code results. Ask the compiler to generate assembly code and then read it. (This doesn't always catch the reality, though. Some compilers leave certain replacements to the linker step.) Or use the machine code and a disassembler and just look. (That always works.) It's not hard to do once you've worked out the steps in your situation.



Let me just suggest some options to consider. Perhaps that's the best I can do. (I'm assuming below that you don't want to take the absolute function of a constant, since there is an obvious "code time" solution for that case.)



  1. The abs() function that's available for your C compiler may very well be implemented in-line with the compiler. (Microsoft's x86 C compiler certainly does this.) If this is already handled within the compiler, looking at the machine code will tell you what you need to know. Sometimes, the assembly output isn't a sufficient test since some compilers will leave this optimization step to the linker process, instead. In those cases, you will have no choice but to examine the final machine code product.

  2. You can attempt to use the method you already mentioned (using an if statement or using the trinary ? operator.) Again, I've seen versions of Microsoft's C compiler that will eat these perfectly well and generate exactly the same case as if you'd used their in-line abs() version -- which for some targets will generate code without any branching involved and taking two or three instructions.

  3. You can use the method you've coded up (which is dependent on your word size.) You've coded one method: $left(n+maskright), text^, mask$.

  4. You could try: $left(n, text^, maskright)-mask$.

  5. You could try: $n-left(left[n << 1right], &: maskright)$ or $n-left(2,n, &: maskright)$ or $n-left(left[n+nright], &: maskright)$.

There are other options if you have a fast multiply for +1 or -1 (sometimes, that's easy.)



Be wary of, and follow, the C standards. Often, operations on negative signed values are undefined. They may behave as expected. But that behavior may not be portable or guaranteed.



As a final note, if you intend on writing a function in C it may pay to provide the compiler hint to make it an inline function.






share|improve this answer











$endgroup$












  • $begingroup$
    @ThePhoton There's already a corner case in (n > 0 ? n : -n). The case where n is the maximal negative value (which that will return unchanged.) I was mostly trying to help list out as many different things to try with the compiler. By the way, which corner case are you considering?
    $endgroup$
    – jonk
    9 hours ago










  • $begingroup$
    I think shifting a signed datatype left (n << 1) is undefined behavior for ANSI C. Multiplying a fixed-width datatype by 2 also risks silent integer overflow.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    @jonk good point on the maximal negative corner case. But this is the behavior even for the standard function right?
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @ElliotAlderson I just checked Harbison and Steele. In the left shift case C defines the behavior regardless of type and it is portable. However, you are right to be worried, in the right shift case, where the C compiler is permitted two different behaviors and it is not portable.
    $endgroup$
    – jonk
    8 hours ago











  • $begingroup$
    @jonk The left shift for negative value is undefined per the standard port70.net/~nsz/c/c11/n1570.html#6.5.7p4 . Worth noting that the standard abs is undefined for the most negative value as well, so it is on par with x < 0 ? -x : x solution.
    $endgroup$
    – Eugene Sh.
    8 hours ago














Your Answer






StackExchange.ifUsing("editor", function ()
return StackExchange.using("schematics", function ()
StackExchange.schematics.init();
);
, "cicuitlab");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "135"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f446457%2fimplementing-absolute-value-function-in-c%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









8












$begingroup$

The standard C library is providing the optimized solutions for many problems with considerations based on the architecture, compiler in use and others. The abs() function defined in stdlib.h is one of these, and it is used for your purpose exactly. To emphasize the point, here is ARM compiler result when using abs vs a version of a homebrew abs: https://arm.godbolt.org/z/aO7t1n



Paste:



#include <stdio.h>
#include <stdlib.h>

int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", abs(x));



results in



main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L4
bl printf
mov r0, #0
pop r4, pc
.L4:
.word .LC0
.LC0:
.ascii "%d1200"


And



#include <stdio.h>
#include <stdlib.h>

int my_abs(int x)

return x < 0 ? -x : x;


int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", my_abs(x));



results in



my_abs:
cmp r0, #0
rsblt r0, r0, #0
bx lr
main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L5
bl printf
mov r0, #0
pop r4, pc
.L5:
.word .LC0
.LC0:
.ascii "%d1200"


Notice that the main code is almost identical in both codes as the my_abs got inlined, and it's implementation is the same as the standard one.






share|improve this answer











$endgroup$












  • $begingroup$
    Your final comment is perfect. Since the result is know at compile time, the codes do not actually calculate the abs.
    $endgroup$
    – vangelo
    9 hours ago











  • $begingroup$
    @vangelo Are you saying I have cheated? :) Well, let me get another example
    $endgroup$
    – Eugene Sh.
    9 hours ago










  • $begingroup$
    Of course not! I'm just pointing out that both codes already show the result in the assembly. :)
    $endgroup$
    – vangelo
    9 hours ago







  • 2




    $begingroup$
    @vangelo OK, then I will leave it to the reader :) Which is by the way another thing. If my_abs was defined in a separate translation unit (source file), the compiler would not know what it does and won't be able to optimize it to a compile-time result. But with standard abs it always knows it.
    $endgroup$
    – Eugene Sh.
    9 hours ago











  • $begingroup$
    Oh well. Here it is: arm.godbolt.org/z/AIzLre One can notice there is no function call at all when using abs.
    $endgroup$
    – Eugene Sh.
    9 hours ago















8












$begingroup$

The standard C library is providing the optimized solutions for many problems with considerations based on the architecture, compiler in use and others. The abs() function defined in stdlib.h is one of these, and it is used for your purpose exactly. To emphasize the point, here is ARM compiler result when using abs vs a version of a homebrew abs: https://arm.godbolt.org/z/aO7t1n



Paste:



#include <stdio.h>
#include <stdlib.h>

int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", abs(x));



results in



main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L4
bl printf
mov r0, #0
pop r4, pc
.L4:
.word .LC0
.LC0:
.ascii "%d1200"


And



#include <stdio.h>
#include <stdlib.h>

int my_abs(int x)

return x < 0 ? -x : x;


int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", my_abs(x));



results in



my_abs:
cmp r0, #0
rsblt r0, r0, #0
bx lr
main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L5
bl printf
mov r0, #0
pop r4, pc
.L5:
.word .LC0
.LC0:
.ascii "%d1200"


Notice that the main code is almost identical in both codes as the my_abs got inlined, and it's implementation is the same as the standard one.






share|improve this answer











$endgroup$












  • $begingroup$
    Your final comment is perfect. Since the result is know at compile time, the codes do not actually calculate the abs.
    $endgroup$
    – vangelo
    9 hours ago











  • $begingroup$
    @vangelo Are you saying I have cheated? :) Well, let me get another example
    $endgroup$
    – Eugene Sh.
    9 hours ago










  • $begingroup$
    Of course not! I'm just pointing out that both codes already show the result in the assembly. :)
    $endgroup$
    – vangelo
    9 hours ago







  • 2




    $begingroup$
    @vangelo OK, then I will leave it to the reader :) Which is by the way another thing. If my_abs was defined in a separate translation unit (source file), the compiler would not know what it does and won't be able to optimize it to a compile-time result. But with standard abs it always knows it.
    $endgroup$
    – Eugene Sh.
    9 hours ago











  • $begingroup$
    Oh well. Here it is: arm.godbolt.org/z/AIzLre One can notice there is no function call at all when using abs.
    $endgroup$
    – Eugene Sh.
    9 hours ago













8












8








8





$begingroup$

The standard C library is providing the optimized solutions for many problems with considerations based on the architecture, compiler in use and others. The abs() function defined in stdlib.h is one of these, and it is used for your purpose exactly. To emphasize the point, here is ARM compiler result when using abs vs a version of a homebrew abs: https://arm.godbolt.org/z/aO7t1n



Paste:



#include <stdio.h>
#include <stdlib.h>

int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", abs(x));



results in



main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L4
bl printf
mov r0, #0
pop r4, pc
.L4:
.word .LC0
.LC0:
.ascii "%d1200"


And



#include <stdio.h>
#include <stdlib.h>

int my_abs(int x)

return x < 0 ? -x : x;


int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", my_abs(x));



results in



my_abs:
cmp r0, #0
rsblt r0, r0, #0
bx lr
main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L5
bl printf
mov r0, #0
pop r4, pc
.L5:
.word .LC0
.LC0:
.ascii "%d1200"


Notice that the main code is almost identical in both codes as the my_abs got inlined, and it's implementation is the same as the standard one.






share|improve this answer











$endgroup$



The standard C library is providing the optimized solutions for many problems with considerations based on the architecture, compiler in use and others. The abs() function defined in stdlib.h is one of these, and it is used for your purpose exactly. To emphasize the point, here is ARM compiler result when using abs vs a version of a homebrew abs: https://arm.godbolt.org/z/aO7t1n



Paste:



#include <stdio.h>
#include <stdlib.h>

int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", abs(x));



results in



main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L4
bl printf
mov r0, #0
pop r4, pc
.L4:
.word .LC0
.LC0:
.ascii "%d1200"


And



#include <stdio.h>
#include <stdlib.h>

int my_abs(int x)

return x < 0 ? -x : x;


int main(void)

srand(111);
int x = rand() - 200;
printf("%dn", my_abs(x));



results in



my_abs:
cmp r0, #0
rsblt r0, r0, #0
bx lr
main:
push r4, lr
mov r0, #111
bl srand
bl rand
sub r1, r0, #200
cmp r1, #0
rsblt r1, r1, #0
ldr r0, .L5
bl printf
mov r0, #0
pop r4, pc
.L5:
.word .LC0
.LC0:
.ascii "%d1200"


Notice that the main code is almost identical in both codes as the my_abs got inlined, and it's implementation is the same as the standard one.







share|improve this answer














share|improve this answer



share|improve this answer








edited 9 hours ago

























answered 9 hours ago









Eugene Sh.Eugene Sh.

8,02119 silver badges31 bronze badges




8,02119 silver badges31 bronze badges











  • $begingroup$
    Your final comment is perfect. Since the result is know at compile time, the codes do not actually calculate the abs.
    $endgroup$
    – vangelo
    9 hours ago











  • $begingroup$
    @vangelo Are you saying I have cheated? :) Well, let me get another example
    $endgroup$
    – Eugene Sh.
    9 hours ago










  • $begingroup$
    Of course not! I'm just pointing out that both codes already show the result in the assembly. :)
    $endgroup$
    – vangelo
    9 hours ago







  • 2




    $begingroup$
    @vangelo OK, then I will leave it to the reader :) Which is by the way another thing. If my_abs was defined in a separate translation unit (source file), the compiler would not know what it does and won't be able to optimize it to a compile-time result. But with standard abs it always knows it.
    $endgroup$
    – Eugene Sh.
    9 hours ago











  • $begingroup$
    Oh well. Here it is: arm.godbolt.org/z/AIzLre One can notice there is no function call at all when using abs.
    $endgroup$
    – Eugene Sh.
    9 hours ago
















  • $begingroup$
    Your final comment is perfect. Since the result is know at compile time, the codes do not actually calculate the abs.
    $endgroup$
    – vangelo
    9 hours ago











  • $begingroup$
    @vangelo Are you saying I have cheated? :) Well, let me get another example
    $endgroup$
    – Eugene Sh.
    9 hours ago










  • $begingroup$
    Of course not! I'm just pointing out that both codes already show the result in the assembly. :)
    $endgroup$
    – vangelo
    9 hours ago







  • 2




    $begingroup$
    @vangelo OK, then I will leave it to the reader :) Which is by the way another thing. If my_abs was defined in a separate translation unit (source file), the compiler would not know what it does and won't be able to optimize it to a compile-time result. But with standard abs it always knows it.
    $endgroup$
    – Eugene Sh.
    9 hours ago











  • $begingroup$
    Oh well. Here it is: arm.godbolt.org/z/AIzLre One can notice there is no function call at all when using abs.
    $endgroup$
    – Eugene Sh.
    9 hours ago















$begingroup$
Your final comment is perfect. Since the result is know at compile time, the codes do not actually calculate the abs.
$endgroup$
– vangelo
9 hours ago





$begingroup$
Your final comment is perfect. Since the result is know at compile time, the codes do not actually calculate the abs.
$endgroup$
– vangelo
9 hours ago













$begingroup$
@vangelo Are you saying I have cheated? :) Well, let me get another example
$endgroup$
– Eugene Sh.
9 hours ago




$begingroup$
@vangelo Are you saying I have cheated? :) Well, let me get another example
$endgroup$
– Eugene Sh.
9 hours ago












$begingroup$
Of course not! I'm just pointing out that both codes already show the result in the assembly. :)
$endgroup$
– vangelo
9 hours ago





$begingroup$
Of course not! I'm just pointing out that both codes already show the result in the assembly. :)
$endgroup$
– vangelo
9 hours ago





2




2




$begingroup$
@vangelo OK, then I will leave it to the reader :) Which is by the way another thing. If my_abs was defined in a separate translation unit (source file), the compiler would not know what it does and won't be able to optimize it to a compile-time result. But with standard abs it always knows it.
$endgroup$
– Eugene Sh.
9 hours ago





$begingroup$
@vangelo OK, then I will leave it to the reader :) Which is by the way another thing. If my_abs was defined in a separate translation unit (source file), the compiler would not know what it does and won't be able to optimize it to a compile-time result. But with standard abs it always knows it.
$endgroup$
– Eugene Sh.
9 hours ago













$begingroup$
Oh well. Here it is: arm.godbolt.org/z/AIzLre One can notice there is no function call at all when using abs.
$endgroup$
– Eugene Sh.
9 hours ago




$begingroup$
Oh well. Here it is: arm.godbolt.org/z/AIzLre One can notice there is no function call at all when using abs.
$endgroup$
– Eugene Sh.
9 hours ago













4












$begingroup$

The speed of a given solution will depend greatly on the architecture, but in C I would say



return (n > 0 ? n : -n);


and let the compiler figure out the best solution.



EDIT: @jonk points out correctly that this will fail for the most-negative possible value of n, assuming that two's-complement arithmetic is used.



Yes, my solution has a conditional branch, but yours has an arithmetic operator and two bitwise operators. Can your microcontroller shift 15 places in a single clock?






share|improve this answer











$endgroup$








  • 2




    $begingroup$
    This is basically just to agree. If a fully portable solution is desirable, do it simple, as you suggested. If the best/shortest/fastest option is needed, it will depend on your processor/compiler and it is very likely that the standard (or non-standard) library will provide the best code.
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @vangelo Just one minor point...I think that the functions in stdlib are defined for int rather than int16_t or uint16_t. The size of an int may be 32 bits, which could influence speed. But you are correct that if an appropriate library function is available it is best to use it.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    I agree. This is why I also mentioned non-standard. It is not uncommon that "extensions" are available and in fact quite common with micro-controllers.
    $endgroup$
    – vangelo
    9 hours ago
















4












$begingroup$

The speed of a given solution will depend greatly on the architecture, but in C I would say



return (n > 0 ? n : -n);


and let the compiler figure out the best solution.



EDIT: @jonk points out correctly that this will fail for the most-negative possible value of n, assuming that two's-complement arithmetic is used.



Yes, my solution has a conditional branch, but yours has an arithmetic operator and two bitwise operators. Can your microcontroller shift 15 places in a single clock?






share|improve this answer











$endgroup$








  • 2




    $begingroup$
    This is basically just to agree. If a fully portable solution is desirable, do it simple, as you suggested. If the best/shortest/fastest option is needed, it will depend on your processor/compiler and it is very likely that the standard (or non-standard) library will provide the best code.
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @vangelo Just one minor point...I think that the functions in stdlib are defined for int rather than int16_t or uint16_t. The size of an int may be 32 bits, which could influence speed. But you are correct that if an appropriate library function is available it is best to use it.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    I agree. This is why I also mentioned non-standard. It is not uncommon that "extensions" are available and in fact quite common with micro-controllers.
    $endgroup$
    – vangelo
    9 hours ago














4












4








4





$begingroup$

The speed of a given solution will depend greatly on the architecture, but in C I would say



return (n > 0 ? n : -n);


and let the compiler figure out the best solution.



EDIT: @jonk points out correctly that this will fail for the most-negative possible value of n, assuming that two's-complement arithmetic is used.



Yes, my solution has a conditional branch, but yours has an arithmetic operator and two bitwise operators. Can your microcontroller shift 15 places in a single clock?






share|improve this answer











$endgroup$



The speed of a given solution will depend greatly on the architecture, but in C I would say



return (n > 0 ? n : -n);


and let the compiler figure out the best solution.



EDIT: @jonk points out correctly that this will fail for the most-negative possible value of n, assuming that two's-complement arithmetic is used.



Yes, my solution has a conditional branch, but yours has an arithmetic operator and two bitwise operators. Can your microcontroller shift 15 places in a single clock?







share|improve this answer














share|improve this answer



share|improve this answer








edited 9 hours ago

























answered 10 hours ago









Elliot AldersonElliot Alderson

9,6812 gold badges12 silver badges22 bronze badges




9,6812 gold badges12 silver badges22 bronze badges







  • 2




    $begingroup$
    This is basically just to agree. If a fully portable solution is desirable, do it simple, as you suggested. If the best/shortest/fastest option is needed, it will depend on your processor/compiler and it is very likely that the standard (or non-standard) library will provide the best code.
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @vangelo Just one minor point...I think that the functions in stdlib are defined for int rather than int16_t or uint16_t. The size of an int may be 32 bits, which could influence speed. But you are correct that if an appropriate library function is available it is best to use it.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    I agree. This is why I also mentioned non-standard. It is not uncommon that "extensions" are available and in fact quite common with micro-controllers.
    $endgroup$
    – vangelo
    9 hours ago













  • 2




    $begingroup$
    This is basically just to agree. If a fully portable solution is desirable, do it simple, as you suggested. If the best/shortest/fastest option is needed, it will depend on your processor/compiler and it is very likely that the standard (or non-standard) library will provide the best code.
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @vangelo Just one minor point...I think that the functions in stdlib are defined for int rather than int16_t or uint16_t. The size of an int may be 32 bits, which could influence speed. But you are correct that if an appropriate library function is available it is best to use it.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    I agree. This is why I also mentioned non-standard. It is not uncommon that "extensions" are available and in fact quite common with micro-controllers.
    $endgroup$
    – vangelo
    9 hours ago








2




2




$begingroup$
This is basically just to agree. If a fully portable solution is desirable, do it simple, as you suggested. If the best/shortest/fastest option is needed, it will depend on your processor/compiler and it is very likely that the standard (or non-standard) library will provide the best code.
$endgroup$
– vangelo
9 hours ago




$begingroup$
This is basically just to agree. If a fully portable solution is desirable, do it simple, as you suggested. If the best/shortest/fastest option is needed, it will depend on your processor/compiler and it is very likely that the standard (or non-standard) library will provide the best code.
$endgroup$
– vangelo
9 hours ago












$begingroup$
@vangelo Just one minor point...I think that the functions in stdlib are defined for int rather than int16_t or uint16_t. The size of an int may be 32 bits, which could influence speed. But you are correct that if an appropriate library function is available it is best to use it.
$endgroup$
– Elliot Alderson
9 hours ago




$begingroup$
@vangelo Just one minor point...I think that the functions in stdlib are defined for int rather than int16_t or uint16_t. The size of an int may be 32 bits, which could influence speed. But you are correct that if an appropriate library function is available it is best to use it.
$endgroup$
– Elliot Alderson
9 hours ago












$begingroup$
I agree. This is why I also mentioned non-standard. It is not uncommon that "extensions" are available and in fact quite common with micro-controllers.
$endgroup$
– vangelo
9 hours ago





$begingroup$
I agree. This is why I also mentioned non-standard. It is not uncommon that "extensions" are available and in fact quite common with micro-controllers.
$endgroup$
– vangelo
9 hours ago












3












$begingroup$

There are a lot of subtle details in using C. Given your comment about speed, it is probably worth your time to try out various options and see which produces better assembly code results. Ask the compiler to generate assembly code and then read it. (This doesn't always catch the reality, though. Some compilers leave certain replacements to the linker step.) Or use the machine code and a disassembler and just look. (That always works.) It's not hard to do once you've worked out the steps in your situation.



Let me just suggest some options to consider. Perhaps that's the best I can do. (I'm assuming below that you don't want to take the absolute function of a constant, since there is an obvious "code time" solution for that case.)



  1. The abs() function that's available for your C compiler may very well be implemented in-line with the compiler. (Microsoft's x86 C compiler certainly does this.) If this is already handled within the compiler, looking at the machine code will tell you what you need to know. Sometimes, the assembly output isn't a sufficient test since some compilers will leave this optimization step to the linker process, instead. In those cases, you will have no choice but to examine the final machine code product.

  2. You can attempt to use the method you already mentioned (using an if statement or using the trinary ? operator.) Again, I've seen versions of Microsoft's C compiler that will eat these perfectly well and generate exactly the same case as if you'd used their in-line abs() version -- which for some targets will generate code without any branching involved and taking two or three instructions.

  3. You can use the method you've coded up (which is dependent on your word size.) You've coded one method: $left(n+maskright), text^, mask$.

  4. You could try: $left(n, text^, maskright)-mask$.

  5. You could try: $n-left(left[n << 1right], &: maskright)$ or $n-left(2,n, &: maskright)$ or $n-left(left[n+nright], &: maskright)$.

There are other options if you have a fast multiply for +1 or -1 (sometimes, that's easy.)



Be wary of, and follow, the C standards. Often, operations on negative signed values are undefined. They may behave as expected. But that behavior may not be portable or guaranteed.



As a final note, if you intend on writing a function in C it may pay to provide the compiler hint to make it an inline function.






share|improve this answer











$endgroup$












  • $begingroup$
    @ThePhoton There's already a corner case in (n > 0 ? n : -n). The case where n is the maximal negative value (which that will return unchanged.) I was mostly trying to help list out as many different things to try with the compiler. By the way, which corner case are you considering?
    $endgroup$
    – jonk
    9 hours ago










  • $begingroup$
    I think shifting a signed datatype left (n << 1) is undefined behavior for ANSI C. Multiplying a fixed-width datatype by 2 also risks silent integer overflow.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    @jonk good point on the maximal negative corner case. But this is the behavior even for the standard function right?
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @ElliotAlderson I just checked Harbison and Steele. In the left shift case C defines the behavior regardless of type and it is portable. However, you are right to be worried, in the right shift case, where the C compiler is permitted two different behaviors and it is not portable.
    $endgroup$
    – jonk
    8 hours ago











  • $begingroup$
    @jonk The left shift for negative value is undefined per the standard port70.net/~nsz/c/c11/n1570.html#6.5.7p4 . Worth noting that the standard abs is undefined for the most negative value as well, so it is on par with x < 0 ? -x : x solution.
    $endgroup$
    – Eugene Sh.
    8 hours ago
















3












$begingroup$

There are a lot of subtle details in using C. Given your comment about speed, it is probably worth your time to try out various options and see which produces better assembly code results. Ask the compiler to generate assembly code and then read it. (This doesn't always catch the reality, though. Some compilers leave certain replacements to the linker step.) Or use the machine code and a disassembler and just look. (That always works.) It's not hard to do once you've worked out the steps in your situation.



Let me just suggest some options to consider. Perhaps that's the best I can do. (I'm assuming below that you don't want to take the absolute function of a constant, since there is an obvious "code time" solution for that case.)



  1. The abs() function that's available for your C compiler may very well be implemented in-line with the compiler. (Microsoft's x86 C compiler certainly does this.) If this is already handled within the compiler, looking at the machine code will tell you what you need to know. Sometimes, the assembly output isn't a sufficient test since some compilers will leave this optimization step to the linker process, instead. In those cases, you will have no choice but to examine the final machine code product.

  2. You can attempt to use the method you already mentioned (using an if statement or using the trinary ? operator.) Again, I've seen versions of Microsoft's C compiler that will eat these perfectly well and generate exactly the same case as if you'd used their in-line abs() version -- which for some targets will generate code without any branching involved and taking two or three instructions.

  3. You can use the method you've coded up (which is dependent on your word size.) You've coded one method: $left(n+maskright), text^, mask$.

  4. You could try: $left(n, text^, maskright)-mask$.

  5. You could try: $n-left(left[n << 1right], &: maskright)$ or $n-left(2,n, &: maskright)$ or $n-left(left[n+nright], &: maskright)$.

There are other options if you have a fast multiply for +1 or -1 (sometimes, that's easy.)



Be wary of, and follow, the C standards. Often, operations on negative signed values are undefined. They may behave as expected. But that behavior may not be portable or guaranteed.



As a final note, if you intend on writing a function in C it may pay to provide the compiler hint to make it an inline function.






share|improve this answer











$endgroup$












  • $begingroup$
    @ThePhoton There's already a corner case in (n > 0 ? n : -n). The case where n is the maximal negative value (which that will return unchanged.) I was mostly trying to help list out as many different things to try with the compiler. By the way, which corner case are you considering?
    $endgroup$
    – jonk
    9 hours ago










  • $begingroup$
    I think shifting a signed datatype left (n << 1) is undefined behavior for ANSI C. Multiplying a fixed-width datatype by 2 also risks silent integer overflow.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    @jonk good point on the maximal negative corner case. But this is the behavior even for the standard function right?
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @ElliotAlderson I just checked Harbison and Steele. In the left shift case C defines the behavior regardless of type and it is portable. However, you are right to be worried, in the right shift case, where the C compiler is permitted two different behaviors and it is not portable.
    $endgroup$
    – jonk
    8 hours ago











  • $begingroup$
    @jonk The left shift for negative value is undefined per the standard port70.net/~nsz/c/c11/n1570.html#6.5.7p4 . Worth noting that the standard abs is undefined for the most negative value as well, so it is on par with x < 0 ? -x : x solution.
    $endgroup$
    – Eugene Sh.
    8 hours ago














3












3








3





$begingroup$

There are a lot of subtle details in using C. Given your comment about speed, it is probably worth your time to try out various options and see which produces better assembly code results. Ask the compiler to generate assembly code and then read it. (This doesn't always catch the reality, though. Some compilers leave certain replacements to the linker step.) Or use the machine code and a disassembler and just look. (That always works.) It's not hard to do once you've worked out the steps in your situation.



Let me just suggest some options to consider. Perhaps that's the best I can do. (I'm assuming below that you don't want to take the absolute function of a constant, since there is an obvious "code time" solution for that case.)



  1. The abs() function that's available for your C compiler may very well be implemented in-line with the compiler. (Microsoft's x86 C compiler certainly does this.) If this is already handled within the compiler, looking at the machine code will tell you what you need to know. Sometimes, the assembly output isn't a sufficient test since some compilers will leave this optimization step to the linker process, instead. In those cases, you will have no choice but to examine the final machine code product.

  2. You can attempt to use the method you already mentioned (using an if statement or using the trinary ? operator.) Again, I've seen versions of Microsoft's C compiler that will eat these perfectly well and generate exactly the same case as if you'd used their in-line abs() version -- which for some targets will generate code without any branching involved and taking two or three instructions.

  3. You can use the method you've coded up (which is dependent on your word size.) You've coded one method: $left(n+maskright), text^, mask$.

  4. You could try: $left(n, text^, maskright)-mask$.

  5. You could try: $n-left(left[n << 1right], &: maskright)$ or $n-left(2,n, &: maskright)$ or $n-left(left[n+nright], &: maskright)$.

There are other options if you have a fast multiply for +1 or -1 (sometimes, that's easy.)



Be wary of, and follow, the C standards. Often, operations on negative signed values are undefined. They may behave as expected. But that behavior may not be portable or guaranteed.



As a final note, if you intend on writing a function in C it may pay to provide the compiler hint to make it an inline function.






share|improve this answer











$endgroup$



There are a lot of subtle details in using C. Given your comment about speed, it is probably worth your time to try out various options and see which produces better assembly code results. Ask the compiler to generate assembly code and then read it. (This doesn't always catch the reality, though. Some compilers leave certain replacements to the linker step.) Or use the machine code and a disassembler and just look. (That always works.) It's not hard to do once you've worked out the steps in your situation.



Let me just suggest some options to consider. Perhaps that's the best I can do. (I'm assuming below that you don't want to take the absolute function of a constant, since there is an obvious "code time" solution for that case.)



  1. The abs() function that's available for your C compiler may very well be implemented in-line with the compiler. (Microsoft's x86 C compiler certainly does this.) If this is already handled within the compiler, looking at the machine code will tell you what you need to know. Sometimes, the assembly output isn't a sufficient test since some compilers will leave this optimization step to the linker process, instead. In those cases, you will have no choice but to examine the final machine code product.

  2. You can attempt to use the method you already mentioned (using an if statement or using the trinary ? operator.) Again, I've seen versions of Microsoft's C compiler that will eat these perfectly well and generate exactly the same case as if you'd used their in-line abs() version -- which for some targets will generate code without any branching involved and taking two or three instructions.

  3. You can use the method you've coded up (which is dependent on your word size.) You've coded one method: $left(n+maskright), text^, mask$.

  4. You could try: $left(n, text^, maskright)-mask$.

  5. You could try: $n-left(left[n << 1right], &: maskright)$ or $n-left(2,n, &: maskright)$ or $n-left(left[n+nright], &: maskright)$.

There are other options if you have a fast multiply for +1 or -1 (sometimes, that's easy.)



Be wary of, and follow, the C standards. Often, operations on negative signed values are undefined. They may behave as expected. But that behavior may not be portable or guaranteed.



As a final note, if you intend on writing a function in C it may pay to provide the compiler hint to make it an inline function.







share|improve this answer














share|improve this answer



share|improve this answer








edited 8 hours ago

























answered 9 hours ago









jonkjonk

37.5k1 gold badge31 silver badges80 bronze badges




37.5k1 gold badge31 silver badges80 bronze badges











  • $begingroup$
    @ThePhoton There's already a corner case in (n > 0 ? n : -n). The case where n is the maximal negative value (which that will return unchanged.) I was mostly trying to help list out as many different things to try with the compiler. By the way, which corner case are you considering?
    $endgroup$
    – jonk
    9 hours ago










  • $begingroup$
    I think shifting a signed datatype left (n << 1) is undefined behavior for ANSI C. Multiplying a fixed-width datatype by 2 also risks silent integer overflow.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    @jonk good point on the maximal negative corner case. But this is the behavior even for the standard function right?
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @ElliotAlderson I just checked Harbison and Steele. In the left shift case C defines the behavior regardless of type and it is portable. However, you are right to be worried, in the right shift case, where the C compiler is permitted two different behaviors and it is not portable.
    $endgroup$
    – jonk
    8 hours ago











  • $begingroup$
    @jonk The left shift for negative value is undefined per the standard port70.net/~nsz/c/c11/n1570.html#6.5.7p4 . Worth noting that the standard abs is undefined for the most negative value as well, so it is on par with x < 0 ? -x : x solution.
    $endgroup$
    – Eugene Sh.
    8 hours ago

















  • $begingroup$
    @ThePhoton There's already a corner case in (n > 0 ? n : -n). The case where n is the maximal negative value (which that will return unchanged.) I was mostly trying to help list out as many different things to try with the compiler. By the way, which corner case are you considering?
    $endgroup$
    – jonk
    9 hours ago










  • $begingroup$
    I think shifting a signed datatype left (n << 1) is undefined behavior for ANSI C. Multiplying a fixed-width datatype by 2 also risks silent integer overflow.
    $endgroup$
    – Elliot Alderson
    9 hours ago










  • $begingroup$
    @jonk good point on the maximal negative corner case. But this is the behavior even for the standard function right?
    $endgroup$
    – vangelo
    9 hours ago










  • $begingroup$
    @ElliotAlderson I just checked Harbison and Steele. In the left shift case C defines the behavior regardless of type and it is portable. However, you are right to be worried, in the right shift case, where the C compiler is permitted two different behaviors and it is not portable.
    $endgroup$
    – jonk
    8 hours ago











  • $begingroup$
    @jonk The left shift for negative value is undefined per the standard port70.net/~nsz/c/c11/n1570.html#6.5.7p4 . Worth noting that the standard abs is undefined for the most negative value as well, so it is on par with x < 0 ? -x : x solution.
    $endgroup$
    – Eugene Sh.
    8 hours ago
















$begingroup$
@ThePhoton There's already a corner case in (n > 0 ? n : -n). The case where n is the maximal negative value (which that will return unchanged.) I was mostly trying to help list out as many different things to try with the compiler. By the way, which corner case are you considering?
$endgroup$
– jonk
9 hours ago




$begingroup$
@ThePhoton There's already a corner case in (n > 0 ? n : -n). The case where n is the maximal negative value (which that will return unchanged.) I was mostly trying to help list out as many different things to try with the compiler. By the way, which corner case are you considering?
$endgroup$
– jonk
9 hours ago












$begingroup$
I think shifting a signed datatype left (n << 1) is undefined behavior for ANSI C. Multiplying a fixed-width datatype by 2 also risks silent integer overflow.
$endgroup$
– Elliot Alderson
9 hours ago




$begingroup$
I think shifting a signed datatype left (n << 1) is undefined behavior for ANSI C. Multiplying a fixed-width datatype by 2 also risks silent integer overflow.
$endgroup$
– Elliot Alderson
9 hours ago












$begingroup$
@jonk good point on the maximal negative corner case. But this is the behavior even for the standard function right?
$endgroup$
– vangelo
9 hours ago




$begingroup$
@jonk good point on the maximal negative corner case. But this is the behavior even for the standard function right?
$endgroup$
– vangelo
9 hours ago












$begingroup$
@ElliotAlderson I just checked Harbison and Steele. In the left shift case C defines the behavior regardless of type and it is portable. However, you are right to be worried, in the right shift case, where the C compiler is permitted two different behaviors and it is not portable.
$endgroup$
– jonk
8 hours ago





$begingroup$
@ElliotAlderson I just checked Harbison and Steele. In the left shift case C defines the behavior regardless of type and it is portable. However, you are right to be worried, in the right shift case, where the C compiler is permitted two different behaviors and it is not portable.
$endgroup$
– jonk
8 hours ago













$begingroup$
@jonk The left shift for negative value is undefined per the standard port70.net/~nsz/c/c11/n1570.html#6.5.7p4 . Worth noting that the standard abs is undefined for the most negative value as well, so it is on par with x < 0 ? -x : x solution.
$endgroup$
– Eugene Sh.
8 hours ago





$begingroup$
@jonk The left shift for negative value is undefined per the standard port70.net/~nsz/c/c11/n1570.html#6.5.7p4 . Worth noting that the standard abs is undefined for the most negative value as well, so it is on par with x < 0 ? -x : x solution.
$endgroup$
– Eugene Sh.
8 hours ago


















draft saved

draft discarded
















































Thanks for contributing an answer to Electrical Engineering Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f446457%2fimplementing-absolute-value-function-in-c%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

Ласкавець круглолистий Зміст Опис | Поширення | Галерея | Примітки | Посилання | Навігаційне меню58171138361-22960890446Bupleurum rotundifoliumEuro+Med PlantbasePlants of the World Online — Kew ScienceGermplasm Resources Information Network (GRIN)Ласкавецькн. VI : Літери Ком — Левиправивши або дописавши її