2

Eg. how can I transform the integer 7 to the float 0.111?

The naive way would be to convert 7 to the string 111, convert that to the integer 111 and then divide by 1000 to get 0.111. Is there a better/faster way, though?

Here's a working example.

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

// Convert 32-bit uint to string
// http://stackoverflow.com/questions/699968/display-the-binary-representation-of-a-number-in-c
const char* bin(uint32_t n){
    uint N = 32;
    static unsigned char ucharBuffer[32+1];
    char *p_buffer = ucharBuffer;

    if(!n)
        return "0";

    // Work from the end of the buffer back
    p_buffer += N;
    *p_buffer-- = '\0';

    //For each bit (going backwards) store character
    while(n){
        if (N-- == 0)
            return NULL;
        *p_buffer-- = ((n & 1) == 1) ? '1' : '0';
        n >>= 1;}

    return p_buffer+1;}


int main(){

    uint INPUT = 7;
    const char *p = bin(INPUT);
    char *end;

    printf("%d -> ", INPUT);
    printf("'%.*s' -> ", (uint)(end-p), p);
    printf("%.3f\n", (double) strtol(p, &end, 10)/1000);

}
étale-cohomology
  • 2,098
  • 2
  • 28
  • 33
  • 1
    Out of curiosity, why are you doing this? It seems an odd conversion, given that under it, e.g. 3 > 3221225471 (0.11 > 0.10111111111111111111111111111111) and 2 = 1 (0.10 = .1). – Ray Aug 24 '16 at 20:09
  • I imagine there is a strange structure being used to represent a floating point value. – jxh Aug 24 '16 at 20:14
  • @Ray So the original motivation is to [construct a Sobol sequence like this](http://www.americanscientist.org/include/popup_fullImage.aspx?key=mAGyoWpHKxq4DbGJIaAyrUVGvdPDqRmPFA5WsU8dgjqivkZFgKQb4A==), but I made I mistake and this question doesn't actually help with that! (I think.) Hopefully it helps someone someday. – étale-cohomology Sep 01 '16 at 23:15
  • 1
    Ah, that makes a bit more sense. jxh's solution is still basically the right approach; you just need to loop over the bits in the opposite direction in order to reverse the sequence. `for (int bit = CHAR_BIT * sizeof(unsigned) - 1; bit >= 0; bit--) { x += (input >> bit) & 1; x /= 10.0; }` – Ray Sep 01 '16 at 23:43

1 Answers1

3

You don't need to convert into a string. C has binary operators that work just fine for this purpose.

double binary_inverse (unsigned input) {
    double x = 0;
    while (input) {
        x += input & 0x1;
        x /= 10;
        input >>= 1;
    }
    return x;
}
jxh
  • 69,070
  • 8
  • 110
  • 193