Module: Nio::Clinger

Defined in:
lib/nio/fmt.rb

Overview

:nodoc: all

Class Method Summary collapse

Class Method Details

.algM(f, e, round_mode, eb = 10, beta = Float::RADIX, n = Float::MANT_DIG, min_e = Float::MIN_EXP-Float::MANT_DIG, max_e = Float::MAX_EXP-Float::MANT_DIG) ⇒ Object



1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
# File 'lib/nio/fmt.rb', line 1244

def algM(f,e,round_mode,eb=10,beta=Float::RADIX,n=Float::MANT_DIG,min_e=Float::MIN_EXP-Float::MANT_DIG,max_e=Float::MAX_EXP-Float::MANT_DIG)

  if e<0
   u,v,k = f,eb**(-e),0
  else
    u,v,k = f*(eb**e),1,0
  end
  
  loop do
     x = u.div(v)
     # overflow if k>=max_e 
     if (x>=beta**(n-1) && x<beta**n) || k==min_e || k==max_e
        return ratio_float(u,v,k,round_mode,beta,n)
     elsif x<beta**(n-1)
       u *= beta
       k -= 1
     elsif x>=beta**n
       v *= beta
       k += 1         
     end     
  end

end

.nextfloat(x) ⇒ Object

valid only for non-negative x



1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
# File 'lib/nio/fmt.rb', line 1284

def nextfloat(x)
  f,e = Math.frexp(x)  
  e = Float::MIN_EXP if f==0
  e = [Float::MIN_EXP,e].max
  dx = Math.ldexp(1,e-Float::MANT_DIG) #Math.ldexp(Math.ldexp(1.0,-Float::MANT_DIG),e)  
  if f==(1.0 - Math.ldexp(1,-Float::MANT_DIG))
    x + dx*2
  else
    x + dx
  end
end

.prevfloat(x) ⇒ Object

valid only for non-negative x



1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
# File 'lib/nio/fmt.rb', line 1297

def prevfloat(x)
  f,e = Math.frexp(x)  
  e = Float::MIN_EXP if f==0
  e = [Float::MIN_EXP,e].max
  dx = Math.ldexp(1,e-Float::MANT_DIG) #Math.ldexp(Math.ldexp(1.0,-Float::MANT_DIG),e)  
  if e==Float::MIN_EXP || f!=0.5 #0.5==Math.ldexp(2**(bits-1),-Float::MANT_DIG)
    x - dx
  else
    x - dx/2 # x - Math.ldexp(Math.ldexp(1.0,-Float::MANT_DIG),e-1)  
  end
end

.ratio_float(u, v, k, round_mode, beta = Float::RADIX, n = Float::MANT_DIG) ⇒ Object



1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
# File 'lib/nio/fmt.rb', line 1268

def ratio_float(u,v,k,round_mode,beta=Float::RADIX,n=Float::MANT_DIG)
  q,r = u.divmod(v)
  v_r = v-r
  z = Math.ldexp(q,k)
  if r<v_r
    z
  elsif r>v_r
    nextfloat z
  elsif (round_mode==:even && q.even?) || (round_mode==:zero)
    z
  else
    nextfloat z
  end
end