Other [challenge] 01 : Subtract without using minus (-)

Subtract two numbers without using the subtract function (aka: minus, -).



***
General 'code challenge' Rules (subject to change):
1. No external links.
2. Give Credit (e.g. "My submission, using Ricky's method.")
3. No attachments.
4. Open to all languages (languages supported in base, preferred).
5. Must compile and run on FreeBSD.
5a. If special libs required; please provide install/compile/run instructions.
6. Respect [new programmers0] (teach [them] something).
7. Try yourself before peaking at other's code.
 
Interesting. I'd have to go back to my bookshelves but vague memory, doing things as unsigned integer of "size" say uint8|16|32_t and adding things like uint8_t.max() winds up wrapping and effectively "subtracting"
 
A simple CPU knows only how to add; he doesn't handle directly any subtract nor multiply, nor divide. All is done by adding. Just use two's complement.

Code:
#include <stdio.h>

int main(void)
{
    int a = 10;
    int b = 2;

    int res = a + ((~b)+1);

    printf("%i - %i = %i\n", a, b, res);
    return 0;
}
 
2s is the direction I went too (bonus: I went a bit overboard on the semantics, comments, and layout of my submission). :)
C:
/**
 * @file minus.c
 *
 * @brief Subtract two numbers without using subtract.
 *
 * @use cc -o minus minus.c
 * @run ./minus
 */
#include <stdio.h>

/**
 * twos --
 * @brief Returns the 2's compliment of a number.
 *
 * @param (int) n - number to return 2's complement of.
 *
 * @return (int) n's 2's complement
 */
int twos(int n) {
    return ~n + 1;          // 2s complement = (bitwise comp + 1)
}

/**
 * Main
 * @param argc            :   number of args
 * @param argv[]          :   array of arguments
 *
 * @return int
 */
int main(int argc, char *argv[]) {

  int numbers[2] = {4, 2};

  /* Calculate the 2s compliment of the second number in list.
   * Add the first and second number to do subtraction without minus.
   */
  int answer = numbers[0] + twos(numbers[1]);
  printf("Subtracting 2 from 4 (without minus): %d\n", answer);

  return 0;
} ///:~

EDIT: Removed guard on `twos()`, per doul's bug report.
 
[challenge] 01 : Subtract without using minus (-)
You know there are already hundreds of programming challenges, puzzles, codegolfing sites out there, right? To name a topical example advent of code. Why do we “need” such threads here too?​
Bash:
dc << EOT
${augend:?}
_${addend:?}
+pq
EOT
In dc(1) the underscore (_) serves the purpose of a negative sign. The dash (-) denotes the (here forbidden) operator. p prints the item on top of the stack, q is quit.​
 
You know there are already hundreds of programming challenges, puzzles, codegolfing sites out there, right? To name a topical example advent of code. Why do we “need” such threads here too?​
Bash:
dc << EOT
${augend:?}
_${addend:?}
+pq
EOT
In dc(1) the underscore (_) serves the purpose of a negative sign. The dash (-) denotes the (here forbidden) operator. p prints the item on top of the stack, q is quit.​
Yes, I do know. But, "I'm sorry"? ...I don't get the impression you're actually looking for my list of reasons, but generally speaking, I thought it would offer some sort of distraction/fun/points of learning/etc.. Again, 'sorry'.

The code submission looks interesting. How you run it (I'm off to read up on dc(1) now)?
 
Ah.
It's been a while but here is your method in (some dialect of; I'm sure...maybe) lisp.
Code:
(defun minus (a b)
  ( (lambda (c)
      (while 
        (< b a)
        (setq b (1+ b)
              c (1+ c))))
   0) )
 
On the topic of precedence:

Can the following (readability aside) allowed to be as well?
int res = a + ((~b)+1);

int res = a + ~b+1;
because, as I look it up, + and ~ have the same precedence so it should follow left->right, correct?


EDIT: I just checked my submission and I had the second form (no parens). So, now I've actually got something to loose here!? :)
 
because, as I look it up, + and ~ have the same precedence so it should follow left->right, correct?
Precedence of '~' is level 2 read right to left
Precedence of '+' is level 4 read left to right

So you're right, I have the (bad?) habit of using more round brackets than necessary. It's avoid silent bug and it's doesn't bloat the final binary. Readability is lowered, intention is clear.
 
I wouldn't call it a bad habit. I do it too (I was just typing fast because you took the "one function version" first. :)). Your's reads far easier to me!

And I think I have it worked out now:
unary operators have higher precedence than binary ones so (let's see if I lay this out correct)...
a + ~b + 1
should become: (a + (~b)) + 1
which is the same as: a + ((~b) + 1)
 
should become: (a + (~b)) + 1
which is the same as: a + ((~b) + 1)
Yes, you're right again, addition is commutative and change order of operations doesn't change the result, doing 1 + a + ~b get the same result. I write code in the way I think, subtraction without '-' sign ? do :

1. one's complement ~b
2. two's complement ~b + 1
3. addition a + ~b + 1

So finally I write a + ((~b) + 1) where round brackets are useless.
 
I write code in the way I think, subtraction without '-' sign ? do :

1. one's complement ~b
2. two's complement ~b + 1
3. addition a + ~b + 1

So finally I write a + ((~b) + 1) where round brackets are useless.
Exactly. That's how think about it too. ...I may have written a + (~b +1) if I wasn't thinking but I thought about it the same as you ..."add 'a' to the '2s of b'". I just happened to not write any parens (probably because I was going for the 'teach' thing and laid it out two different ways).
 
Back
Top