#!/usr/bin/perl

use 5.038.2;
# no utf8;

# Uso: se le pasa un binario y devuelve el número 
# o viceversa.

# Hay que ahorrar espacio (y energía) en los soportes digitales.

# Si no devuelve nada es que no es int16 o unsigned short int (que es lo deseable)

# int16();     # debug on
# my $n = 0;  
# say int16( $n );

# $n = 2**15;
# say int16( $n );
# $n = - 2**15;
# say int16( $n );
# $n = "\0\0";
# say int16( $n );
# $n = "\0";
# say int16( $n );

say "Test extensivo:";
for (my $i = -(2**16)/2 ; $i <= (2**16)/2 -1; $i++){
    print $i, 
      " -> " . 
      prettyprint(short($i)) . 
      " or " , 
      short(short($i)) , 
      " " x 9 ;                       # apto para monitores 8k
    print "\n" if ($i % 7== 0);       # ncols = 7
}
say "";

exit 3;


sub short {
    my $cosa = shift;
reciclado:    
    if ( $cosa =~ /^\-?\d+$/g ) {          # se devuelve cosa de número
	return unless ( 0+$cosa eq $cosa );
	return if $cosa < -32768;
	return if $cosa > 32767;
	return if (int($cosa) != $cosa);           # Error: no int   /* se supone que int es como un redondeo a 0, truncamiento */
	return pack( "s", $cosa );
    }elsif ($cosa =~ /^\-?\d+\.\d+/){
	return if ($cosa =~ /^\-?\d+\.\d+e/);      # flotante muy flotante
	$cosa = int( $cosa );
	goto reciclado;
    }else{
	return if (length($cosa) != 2);                # problema de si se manda un char a un short ???
	return +(unpack( "s", $cosa ));                   # unpackea lo que sea si es de short num bytes
    }
}

sub prettyprint {
    my $lin = shift;
    my @bytes2 = split //, $lin;
    my $string = ord($bytes2[0]) . " " . ord($bytes2[1]);    # esto no es ascii porque es hasta 255, todo caso e-ascii
    return $string;                                          # mejor que hexadecimal de aquí a Lima
}







__END__

Esta parte da un poco de vergüenza, pero intenté hacerlo 
  todo a pelo. mié 04 feb 2026 23:04:06 CET
El caso es, que ya tenemos la subrutina para números 
  pequeños de vuelta a casa. No ocupan, casi :)
  Como en los 80286!








sub int16 {
    my $cosa = shift;
    state $debug_int16;
    state $count;
    unless (defined $cosa){
	$debug_int16 = ++$count % 2;                    # a modo de init debug switch on and off 
	return if $debug_int16 == 1;                    # vale, ahora tengo un debug que no uso
	return $count if $debug_int16 == 0;
    }      


# tomado de /usr/include/limits.h
# ve tú a saber en Rust
# /* Minimum and maximum values a `signed short int' can hold.  */
  #  define SHRT_MIN      (-32768)
  #  define SHRT_MAX      32767
  

#   my $bytes = 2;     # 16 bits, 15 bits + signo
    my $nbytedcha = 2**8;                 # 256, neto, 0-255
    my $nbyteizda = 2**7;                 # se pierde un bit en el signo. C'est la vie
    my $number;
    my $numerototal = 2**15;    # el unsigned int16 - 1 bit para el signo
    
    if ( $cosa =~ /[\-|\d]/g ) {          # se devuelve cosa de número
	$number = $cosa;
	
	return if (int($number) != $number);           # Error: no int
	
	my $limit = $numerototal / 2 ;       # par entre 2 = par ; pos + 0, neg
	my $minor = - $limit;
	return if $number < $minor;                    # Error: menor int16
	my $mayor = 0 + $limit -1;           # dejar hueco al 0
	return if $number > $mayor;                    # Error: mayor int16
    
	my $store = " " x 2;    # 2 bytes de los de antes de unicode (char)
	my $minorbyte = abs( $number % $nbytedcha ) ;    # 0 - 255 = $nbytedcha posibilidades
	my $mayorbyte = 0;
	if ($number == 0){
	    $mayorbyte = 0 ;
	}else{
	    $mayorbyte = 1+ abs($number) - int( abs($number) / $nbytedcha ) * $nbytedcha ;  # 0 - 127 = $nbyteizda  
        }
	
       	if ($number < 0){
	    $mayorbyte = chr(127 + $mayorbyte); # 0 - 127 pos 128 - 255 neg
	}
	substr $store, 0, 1, chr($mayorbyte);
	substr $store, 1, 1, chr($minorbyte);	
	return $store;
	
    }else{                                           # pack binario de int16
	return if (length($cosa != 2));        # Error: no son 2 bytes
	return unless ($cosa =~ /(.)(.)/);     # Error: wide-char in bytes
	$number = 0 unless defined $2;
	return ord($2) unless defined $1; 
	# se devuelve número de cosa
	if (ord($1) <= 127){
	    $number = ord($1) * $nbytedcha + ord($2);
	}else{
	    $number = - (ord($1)-127) * $nbytedcha + ord($2);
	}
	return $number;
    }
}


