<commit_before>#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
#include "fail.h"
#include "memory.h"
#include "mlvalues.h"
#include "misc.h"
#include "stacks.h"

#ifdef ALIGN_DOUBLE

#if defined(__GNUC__) && defined(__sparc__)

/* GCC for the Sparc is the major offender here, since it uses ldd and std
   to operate on doubles, therefore requiring 8-alignment of doubles.
   This is a hack to coerce GCC into generating the right code: two ld
   or two st. */

inline double Double_val(val)
     value val;
{
  double result;
  asm("ld [%1], %0; ld [%1+4], %R0" : "=f" (result) : "r" (val));
  return result;
}

inline void Store_double_val(val, dbl)
     value val;
     double dbl;
{
  asm("st %0, [%1]; st %R0, [%1+4]" : : "r" (dbl), "r" (val));
}

#else

double Double_val(val)
     value val;
{
  union { value v[2]; double d; } buffer;

  Assert(sizeof(double) == 2 * sizeof(value));
  buffer.v[0] = Field(val, 0);
  buffer.v[1] = Field(val, 1);
  return buffer.d;
}

void Store_double_val(val, dbl)
     value val;
     double dbl;
{
  union { value v[2]; double d; } buffer;

  Assert(sizeof(double) == 2 * sizeof(value));
  buffer.d = dbl;
  Field(val, 0) = buffer.v[0];
  Field(val, 1) = buffer.v[1];
}

#endif
#endif

value copy_double(d)
     double d;
{
  value res;

#define Setup_for_gc
#define Restore_after_gc
  Alloc_small(res, Double_wosize, Double_tag);
#undef Setup_for_gc
#undef Restore_after_gc
  Store_double_val(res, d);
  return res;
}

value format_float(fmt, arg)    /* ML */
     value fmt, arg;
{
  char format_buffer[64];
  int prec, i;
  char * p;
  char * dest;
  value res;

  prec = 64;
  for (p = String_val(fmt); *p != 0; p++) {
    if (*p >= '0' && *p <= '9') {
      i = atoi(p) + 15;
      if (i > prec) prec = i;
      break;
    }
  }
  for( ; *p != 0; p++) {
    if (*p == '.') {
      i = atoi(p+1) + 15;
      if (i > prec) prec = i;
      break;
    }
  }
  if (prec <= sizeof(format_buffer)) {
    dest = format_buffer;
  } else {
    dest = stat_alloc(prec);
  }
  sprintf(dest, String_val(fmt), Double_val(arg));
  res = copy_string(dest);
  if (dest != format_buffer) {
    stat_free(dest);
  }
  return res;
}

value float_of_string(s)        /* ML */
     value s;
{
  return copy_double(atof(String_val(s)));
}

value int_of_float(f)           /* ML */
     value f;
{
  return Val_long((long) Double_val(f));
}

value float_of_int(n)           /* ML */
     value n;
{
  return copy_double((double) Long_val(n));
}

value neg_float(f)              /* ML */
     value f;
{
  return copy_double(- Double_val(f));
}

value add_float(f, g)         /* ML */
     value f, g;
{
  return copy_double(Double_val(f) + Double_val(g));
}

value sub_float(f, g)         /* ML */
     value f, g;
{
  return copy_double(Double_val(f) - Double_val(g));
}

value mul_float(f, g)         /* ML */
     value f, g;
{
  return copy_double(Double_val(f) * Double_val(g));
}

value div_float(f, g)         /* ML */
     value f, g;
{
  double dg = Double_val(g);
  if (dg == 0.0) raise_zero_divide();
  return copy_double(Double_val(f) / dg);
}

value exp_float(f)              /* ML */
     value f;
{
  return copy_double(exp(Double_val(f)));
}

value log_float(f)              /* ML */
     value f;
{
  return copy_double(log(Double_val(f)));
}

value sqrt_float(f)             /* ML */
     value f;
{
  return copy_double(sqrt(Double_val(f)));
}

value power_float(f, g)         /* ML */
     value f, g;
{
  return copy_double(pow(Double_val(f), Double_val(g)));
}

value sin_float(f)              /* ML */
     value f;
{<commit_msg>Division par 0.0 ne declenche plus Division_by_zero (c'est le modele IEEE 754, les amis).<commit_after>#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
#include "fail.h"
#include "memory.h"
#include "mlvalues.h"
#include "misc.h"
#include "stacks.h"

#ifdef ALIGN_DOUBLE

#if defined(__GNUC__) && defined(__sparc__)

/* GCC for the Sparc is the major offender here, since it uses ldd and std
   to operate on doubles, therefore requiring 8-alignment of doubles.
   This is a hack to coerce GCC into generating the right code: two ld
   or two st. */

inline double Double_val(val)
     value val;
{
  double result;
  asm("ld [%1], %0; ld [%1+4], %R0" : "=f" (result) : "r" (val));
  return result;
}

inline void Store_double_val(val, dbl)
     value val;
     double dbl;
{
  asm("st %0, [%1]; st %R0, [%1+4]" : : "r" (dbl), "r" (val));
}

#else

double Double_val(val)
     value val;
{
  union { value v[2]; double d; } buffer;

  Assert(sizeof(double) == 2 * sizeof(value));
  buffer.v[0] = Field(val, 0);
  buffer.v[1] = Field(val, 1);
  return buffer.d;
}

void Store_double_val(val, dbl)
     value val;
     double dbl;
{
  union { value v[2]; double d; } buffer;

  Assert(sizeof(double) == 2 * sizeof(value));
  buffer.d = dbl;
  Field(val, 0) = buffer.v[0];
  Field(val, 1) = buffer.v[1];
}

#endif
#endif

value copy_double(d)
     double d;
{
  value res;

#define Setup_for_gc
#define Restore_after_gc
  Alloc_small(res, Double_wosize, Double_tag);
#undef Setup_for_gc
#undef Restore_after_gc
  Store_double_val(res, d);
  return res;
}

value format_float(fmt, arg)    /* ML */
     value fmt, arg;
{
  char format_buffer[64];
  int prec, i;
  char * p;
  char * dest;
  value res;

  prec = 64;
  for (p = String_val(fmt); *p != 0; p++) {
    if (*p >= '0' && *p <= '9') {
      i = atoi(p) + 15;
      if (i > prec) prec = i;
      break;
    }
  }
  for( ; *p != 0; p++) {
    if (*p == '.') {
      i = atoi(p+1) + 15;
      if (i > prec) prec = i;
      break;
    }
  }
  if (prec <= sizeof(format_buffer)) {
    dest = format_buffer;
  } else {
    dest = stat_alloc(prec);
  }
  sprintf(dest, String_val(fmt), Double_val(arg));
  res = copy_string(dest);
  if (dest != format_buffer) {
    stat_free(dest);
  }
  return res;
}

value float_of_string(s)        /* ML */
     value s;
{
  return copy_double(atof(String_val(s)));
}

value int_of_float(f)           /* ML */
     value f;
{
  return Val_long((long) Double_val(f));
}

value float_of_int(n)           /* ML */
     value n;
{
  return copy_double((double) Long_val(n));
}

value neg_float(f)              /* ML */
     value f;
{
  return copy_double(- Double_val(f));
}

value add_float(f, g)         /* ML */
     value f, g;
{
  return copy_double(Double_val(f) + Double_val(g));
}

value sub_float(f, g)         /* ML */
     value f, g;
{
  return copy_double(Double_val(f) - Double_val(g));
}

value mul_float(f, g)         /* ML */
     value f, g;
{
  return copy_double(Double_val(f) * Double_val(g));
}

value div_float(f, g)         /* ML */
     value f, g;
{
  double dg = Double_val(g);
  return copy_double(Double_val(f) / dg);
}

value exp_float(f)              /* ML */
     value f;
{
  return copy_double(exp(Double_val(f)));
}

value log_float(f)              /* ML */
     value f;
{
  return copy_double(log(Double_val(f)));
}

value sqrt_float(f)             /* ML */
     value f;
{
  return copy_double(sqrt(Double_val(f)));
}

value power_float(f, g)         /* ML */
     value f, g;
{
  return copy_double(pow(Double_val(f), Double_val(g)));
}

value sin_float(f)              /* ML */
     value f;
{
{'fraction_non_alphanumeric': 0.16390728476821192, 'fraction_numerical': 0.010899558498896247, 'mean_word_length': 2.6834349593495936, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7509491', 'n_tokens_mistral': 2928, 'n_tokens_neox': 2851, 'n_words': 725}