I'm trying to kind of translate a program from Ruby to C, using this GMP library and I'm struggling to understand a few things that are not even directly related to GMP but as I'm using GMP and I may have more questions in the future, I created this thread with this name, to be able to use it in the future.
The thing is that I'm trying to convert a number into it's binary representation using the GMP library function mpz_export() which is supposed to fill in an array of words with data from the given number. Here is the documentation for this function:
I have a few doubts/questions here, about some of the parameters of this function and how things should look like inside the array of words:GMP library wrote:
Function: void * mpz_export (void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, const mpz_t op)
Fill rop with word data from op.
The parameters specify the format of the data produced. Each word will be size bytes and order can be 1 for most significant word first or -1 for least significant first. Within each word endian can be 1 for most significant byte first, -1 for least significant first, or 0 for the native endianness of the host CPU. The most significant nails bits of each word are unused and set to zero, this can be 0 to produce full words.
The number of words produced is written to *countp, or countp can be NULL to discard the count. rop must have enough space for the data, or if rop is NULL then a result array of the necessary size is allocated using the current GMP allocation function (see Custom Allocation). In either case the return value is the destination used, either rop or the allocated block.
If op is non-zero then the most significant word produced will be non-zero. If op is zero then the count returned will be zero and nothing written to rop. If rop is NULL in this case, no block is allocated, just NULL is returned.
The sign of op is ignored, just the absolute value is exported. An application can use mpz_sgn to get the sign and handle it as desired. (see Comparison Functions)
There are no data alignment restrictions on rop, any address is allowed.
When an application is allocating space itself the required size can be determined with a calculation like the following. Since mpz_sizeinbase always returns at least 1, count here will be at least one, which avoids any portability problems with malloc(0), though if z is zero no space at all is actually needed (or written).
numb = 8*size - nail;
count = (mpz_sizeinbase (z, 2) + numb-1) / numb;
p = malloc (count * size);
1 - A word has always a fixed length or it can be changed?? And here I'm referring to a word in general computing, not specifically in the context of GMP library.
2 - In general computing, isn't a word a stream of 8 bits (1 byte)? Maybe the wording is not the most correct, but you get the point, I hope?
3 - One of the parameters of mpz_export() is size_t size which holds the "word size". If, in general computing, a word has 8 bits (or 1 byte), what effect will this parameter have in the array of words of data from the number to be converted? I ask this because if the size of a word is usually 8 bit and it's a thing of the architecture of the machine the code is running in, why we have a parameter to change it?
After what I said above, I'll show here a piece of code with different values for that size_t size parameter so that someone can explain me te effect of changing the value of this parameter in the resuting array of words, because I cannot understand what I see.
Code 1:
Here I gave the value 8 to the parameter size_t size.
The printf I have in the code prints 0.
Code: Select all
#include <stdio.h>
#include <gmp.h>
#include <inttypes.h>
int main(void){
uint8_t bin_array[1024];
uint8_t order = 1, endian = 1;
size_t countp = 0, size = 8, nails = 0;
mpz_t op;
mpz_init(op);
mpz_set_str(op, "1000", 0);
countp = mpz_sizeinbase(op, 2);
printf("countp: %lu\n", countp);
mpz_export(bin_array, &countp, order, size, endian, nails, op);
printf("bin_arr[0]: %d\n", bin_array[0]);
mpz_clear(op);
return 0;
}
I gave the value of sizeof(unsigned char) to the parameter size_t size.
The printf in the end, prints 3.
Code: Select all
#include <stdio.h>
#include <gmp.h>
#include <inttypes.h>
int main(void){
uint8_t bin_array[1024];
uint8_t order = 1, endian = 1;
size_t countp = 0, size = sizeof(unsigned char), nails = 0;
mpz_t op;
mpz_init(op);
mpz_set_str(op, "1000", 0);
countp = mpz_sizeinbase(op, 2);
printf("countp: %lu\n", countp);
mpz_export(bin_array, &countp, order, size, endian, nails, op);
printf("bin_arr[0]: %d\n", bin_array[0]);
mpz_clear(op);
return 0;
}