-4

I've got two integer numbers in binary form, num1 and num2 stored as strings containing "0"s and "1"s.

What would be the best algorithm to divide num1 by num2 in order to obtain a floating-point double result?

rmaddy
  • 298,130
  • 40
  • 468
  • 517
Desmond Hume
  • 6,732
  • 13
  • 57
  • 104
  • 1
    Maximum size of strings? – keith Dec 30 '17 at 20:54
  • @keith Character quantity is arbitrary but `size(string1) == size(string2)` is always true – Desmond Hume Dec 30 '17 at 20:56
  • The term ‘string’ has different meanings in each of the three languages. Which are you really working with? How do you represent a floating point value in your system? How do you know where the binary point is? How many digits in the result? – Jonathan Leffler Dec 30 '17 at 20:58
  • @JonathanLeffler C null-terminated string – Desmond Hume Dec 30 '17 at 20:58
  • @JonathanLeffler Floating point numbers are represented as 8 bytes long `double` – Desmond Hume Dec 30 '17 at 20:59
  • I would think converting the values to units of the machine word size and then simply implementing the by-hand long division algorithm. Stop when you have enough result bits to fill your FP result type. – SoronelHaetir Dec 30 '17 at 21:03
  • @SoronelHaetir "by-hand long division algorithm"? – Desmond Hume Dec 30 '17 at 21:05
  • Define "best". Performance wise? Simplicity of writing? Precision? I'd bet that converting them into doubles and writing `n1/n2` would be simple and efficient. – Avishai Y Dec 30 '17 at 21:07
  • I would just convert to `base 10` and do the division regularly using `doubles`. Why use `1` and `0` to divide? – Ivan86 Dec 30 '17 at 21:09
  • In my opinion it's much easier to make a base 2 to base 10 converter and then do the division than it is to make a binary dividing function. – Ivan86 Dec 30 '17 at 21:10
  • 1
    @Ivan86 - Why does base 10 need to be involved here? – Oliver Charlesworth Dec 30 '17 at 21:20
  • @OliverCharlesworth Since they are integers in binary form why not just convert them to decimal and then do the operation. Otherwise if he wished to do this in binary [this](https://www.wikihow.com/Divide-Binary-Numbers) would be useful. – Ivan86 Dec 30 '17 at 21:24
  • He would need a function for division and a function for subtraction of binary numbers. – Ivan86 Dec 30 '17 at 21:24
  • @Ivan86 - I guess you mean parse the values to `[long] int` or whatever? That doesn't involve decimal, though. – Oliver Charlesworth Dec 30 '17 at 21:26
  • @OliverCharlesworth Sorry about that I meant `base 10` (decadic) not decimal. – Ivan86 Dec 30 '17 at 21:27
  • @Ivan86 - It doesn't involve base 10, either ;) – Oliver Charlesworth Dec 30 '17 at 21:28
  • @OliverCharlesworth Sorry if I was unclear but both the answers below say what I was saying. It is not binary division though. – Ivan86 Dec 30 '17 at 21:31
  • @Ivan86 - Sure. All I'm saying is that there's no decimal/base10 involved anywhere here. – Oliver Charlesworth Dec 30 '17 at 21:32
  • @OliverCharlesworth I understand, but I don't see an advantage to binary division over regular division so that's why I added that comment. There are some good methods to divide decimal numbers with practically arbitrary precision. – Ivan86 Dec 30 '17 at 21:38
  • @OliverCharlesworth Something like [this](https://codegolf.stackexchange.com/questions/22146/implement-arbitrary-precision-division). – Ivan86 Dec 30 '17 at 21:41
  • `double quotient = 1.0L * strtoumax(num1, 0,2)/strtoumax(num1, 0,2);` is a start. – chux - Reinstate Monica Dec 30 '17 at 22:14

3 Answers3

1

Assuming your strings are in big-endian binary format, which is the most natural way to represent a binary number as a string, here is how you could convert each str to a double val:

double val = 0.0;
while (0 != *str) {
    val *= 2.0;
    if ('1' == *str) val += 1.0;
    str++;
}

Then divide the doubles.

Doug Currie
  • 38,699
  • 1
  • 88
  • 113
0
#include<iostream>
#include<cmath>
int stringToNum(std::string str){
  int num=0;
  for(size_t i=0;i<str.size();i++){
    if(str[i]=='1'){num+=pow(2,str.size()-i-1);}
  }
 return num;
}

int main(){
   std::string str1,str2;
   std::cin>>str1>>str2;
   int num1 = stringToNum(str1);
   int num2 = stringToNum(str2);
   std::cout << (float)num1/num2 << '\n';
}
haichuan
  • 1
  • 1
0

Code could follow primary school math.

Align the dividend and divisor.  
Loop DOUBLE_BITS times  
  Test divisor and dividend  
  If big enough, subtract and add to quotient   
  Shift  

Below is untested code, so treat as pseudo-code to OP an idea of a solution.

double str_div(const char * num1, const char *num2) {
  while (*num1 == '0') num1++;  // find ms bit
  while (*num2 == '0') num2++;
  if (*num2 == '\0') {
    if (*num1) return 1.0/0.0;
    return 0.0/0.0; 
  }
  size_t sz1 = strlen(num1) + 1;
  size_t sz2 = strlen(num2) + 1;
  double m = pow(2, 1.0* sz1 - sz2);
  #define DOUBLE_BITS 53
  size_t szmx = max(sz1, sz2); 
  size_t sza = szmx  + DOUBLE_BITS + 1;

  // form working register `a`
  char *a = malloc(sza);
  memset(a, '0', sza);
  memcpy(a, num1, sz1 - 1);
  a[sz1 - 1] = '\0';
  double quotient = 0.0;
  for (size_t i=0; i<DOUBLE_BITS; i++) {
    if (str_ge(a, num2)) {  // a >= num2?
      str_sub(a, num2);     // a -= num2
      quotient += m; 
    }
    m /= 2.0;
  }
  free(a);
  return quotient;
}
chux - Reinstate Monica
  • 113,725
  • 11
  • 107
  • 213