En mi cálculo, la función rand(); en lenguaje C genera un número de 32 bits.
¿El siguiente código generará un número uint_8 aleatorio? ¿O puede depender de la plataforma?
uint8_t var=(uint8_t) rand();No quiero usar la operación de módulo, debido a la complejidad del tiempo de cálculo del módulo.
De hecho, este código convertirá el valor de retorno de rand en un valor de tipo uint8_t . La conversión ocurre esencialmente truncando todos menos los 8 bits de orden más bajo.
En cuanto al uso del operador de módulo, la mayoría de los compiladores son lo suficientemente inteligentes como para convertir módulo por 2 n en un AND bit a bit con un valor con los n bits de orden inferior establecidos.
Tenga en cuenta que para usos simples esto está bien, sin embargo, si desea generar números aleatorios adecuados para fines criptográficos, o si desea garantizar una mejor distribución aleatoria, debe usar una biblioteca criptográfica como OpenSSL en lugar de la función rand .
No quiero usar la operación de módulo, debido a la complejidad del tiempo de cálculo del módulo.
Los compiladores modernos son lo suficientemente inteligentes como para no usar la división cuando no es absolutamente necesario.
Todo lo siguiente da como resultado el código generado idéntico:
uint8_t foo(void) { return rand(); } uint8_t foo1(void) { return (uint8_t)rand(); } uint8_t foo2(void) { return rand() % 0x100; } uint8_t foo3(void) { return rand() & 0xff; }Y el código generado:
foo(): sub rsp, 8 call rand add rsp, 8 ret foo1(): sub rsp, 8 call rand add rsp, 8 ret foo2(): sub rsp, 8 call rand add rsp, 8 ret foo3(): sub rsp, 8 call rand add rsp, 8 retSi el rendimiento es clave, este código sería la forma más rápida, porque no desperdiciará 3/4 de la función rand() .
Solo se garantiza que la función PS rand() regrese con un número entero de 16 bits, por lo que podría volverse problemático cuando su máquina no regresa con un número entero de 32 bits.
#include <stdio.h> #include <stdlib.h> #include <stdint.h> int main(int argc, char *argv[]){ /* typedef struct __attribute__((packed)) _fourbytes{ uint8_t b0; uint8_t b1; uint8_t b2; uint8_t b3; } FOURBYTES; */ typedef union __attribute__((packed)) _doubleword{ /* FOURBYTES byte; */ uint32_t dw; uint8_t byte[4]; } DOUBLEWORD; DOUBLEWORD random_var; random_var.dw = rand(); for(int i = 0; i < 4; i++){ printf("random_var.byte[%d] = %d\n", i, random_var.byte[i]); } return 0; }