VALUE probabilities_from_h( VALUE self, VALUE hash ) { VALUE obj; ProbabilityList *pl; double error; Check_Type( hash, T_HASH ); obj = pl_alloc( Probabilities ); pl = get_probability_list( obj ); // Set these up so that they get adjusted during hash iteration pl->offset = 0x7fffffff; pl->slots = 0; // First iteration establish min/max and validate all key/values rb_hash_foreach( hash, validate_key_value, obj ); alloc_probs_iv( pl, pl->slots, 0.0 ); // Second iteration copy key/value pairs into structure rb_hash_foreach( hash, copy_key_value, obj ); error = calc_cumulative( pl ) - 1.0; if ( error < -1.0e-8 ) { rb_raise( rb_eArgError, "Total probabilities are less than 1.0" ); } else if ( error > 1.0e-8 ) { rb_raise( rb_eArgError, "Total probabilities are greater than 1.0" ); } return obj; }
void * pc_alloc(struct pcache *pc) { struct pool *pp; struct pc_pool *pcp, **item; abort_unless(pc); if ( l_isempty(&pc->avail) ) { if ( l_isempty(&pc->full) ) { if ( ! pc->mm || (pc->npools == pc->maxpools) ) return NULL; pcp = mem_get(pc->mm, pc->pgsiz); if ( ! pcp ) return NULL; pc_addpg(pc, pcp, pc->pgsiz); } else { pcp = (struct pc_pool *)pc->full.next; l_rem(&pcp->entry); l_ins(pc->avail.prev, &pcp->entry); } } pcp = (struct pc_pool *)pc->avail.next; pp = &pcp->pool; if ( pp->fill == 1 ) { l_rem(&pcp->entry); l_ins(&pc->empty, &pcp->entry); } item = pl_alloc(pp); *item = pcp; return (char *)item + sizeof(cat_pcpad_t); }
VALUE probabilities_for_fair_die( VALUE self, VALUE sides ) { int s = NUM2INT( sides ); VALUE obj; ProbabilityList *pl; if ( s < 1 ) { rb_raise( rb_eArgError, "Number of sides should be 1 or more" ); } if ( s > 100000 ) { rb_raise( rb_eArgError, "Number of sides should be less than 100001" ); } obj = pl_alloc( Probabilities ); pl = get_probability_list( obj ); pl->offset = 1; alloc_probs_iv( pl, s, 1.0/s ); return obj; }