little refresher on how "new" works/what it is/is for: https://wiki.kolmafia.us/index.php?title=New
now, what's the issue? Let's start with mafia's "normal" behavior:
and
Everything's fine here. You send a float when an int is expected? the decimal part is cropped. You send an int when a float is expected? it adds ".0" to it.
So, what's the issue? Well, as you may know, "new" assigns the parameters in the order they are place IN THE RECORD. This means that
will return:
Returned: record example
str => aaa
loc => The Dire Warren
BUT
will return:
string found when location expected for field #2 (loc) ()
Returned: void
As you can see, it doesn't "look for a match" when assigning, it just matches the parameters in order. If it can't, it aborts.
However, when talking about int <=> float, it doesn't seem to have that "problem" (the "it aborts if it fails")... at all??? (in a bad way; the "there's no way something isn't broken" kind of way)
returns:
Returned: record test_record_type
i => 2.5
flt => 10
...the integer field got assigned a float; the float field got assigned an integer
Here's a way to showcase this: (these code blocks will be grouped 2 by 2. Between them, only the function at the start (and its call) will be different)
float => int:
returns:
The value of a_float is: 53.0
Returned: record a_record_containing_only_a_float_field
flt => 53
returns:
The value of an_integer is: 53
Returned: record a_record_containing_only_a_float_field
flt => 53
int => float:
returns:
The value of an_integer is: 41
Returned: record a_record_containing_only_an_integer_field
i => 41.7
returns:
The value of a_float is: 41.7
Returned: record a_record_containing_only_an_integer_field
i => 41.7
Overall, all this would just be a "fun little fact" if it wasn't for memory-related worries: the values are either stored as they should with their datatype, or not.
What this means: if they are stored correctly, the maximum values just changed: for ints, the maximum is no longer 2 147 483 647.
If they are NOT, then this is an issue regarding memory. We're talking about OVERFLOW and UNDERFLOW: a float which became an int may be modified/may modify the previous thing stored in memory, because of the possibly added 16 bits of memory. For an int, it may impact/be impacted by the next, because of the possible 16 bits "added" to account for the decimal part.
now, what's the issue? Let's start with mafia's "normal" behavior:
Code:
> ash int x; x=3.5; return x
Returned: 3
Code:
> ash float x; x=3; return x
Returned: 3.0
Everything's fine here. You send a float when an int is expected? the decimal part is cropped. You send an int when a float is expected? it adds ".0" to it.
So, what's the issue? Well, as you may know, "new" assigns the parameters in the order they are place IN THE RECORD. This means that
Code:
record example { string str; location loc;} a_record_that_WILL_see_the_light_of_day = new example("aaa", $location[the dire warren]);
Returned: record example
str => aaa
loc => The Dire Warren
BUT
Code:
record example { string str; location loc;} a_record_that_will_NEVER_see_the_light_of_day = new example($location[the dire warren], "aaa");
string found when location expected for field #2 (loc) ()
Returned: void
As you can see, it doesn't "look for a match" when assigning, it just matches the parameters in order. If it can't, it aborts.
However, when talking about int <=> float, it doesn't seem to have that "problem" (the "it aborts if it fails")... at all??? (in a bad way; the "there's no way something isn't broken" kind of way)
Code:
record test_record_type {
int i;
float flt;
} my_record = new test_record_type(2.5, 10);
return my_record;
returns:
Returned: record test_record_type
i => 2.5
flt => 10
...the integer field got assigned a float; the float field got assigned an integer
Here's a way to showcase this: (these code blocks will be grouped 2 by 2. Between them, only the function at the start (and its call) will be different)
float => int:
Code:
void function_who_wants_a_float(float a_float)
{ print("The value of a_float is: " + a_float);}
//function which expects a float, and prints it
record a_record_containing_only_a_float_field {
float flt;
} record_name = new a_record_containing_only_a_float_field(53);
//This record's only field (a float) just got filled with an integer... not a big deal, right? should just be turned into 53.0, right?
function_who_wants_a_float( record_name.flt );
return record_name;
The value of a_float is: 53.0
Returned: record a_record_containing_only_a_float_field
flt => 53
Code:
void function_who_wants_an_integer(int an_integer)
{ print("The value of an_integer is: " + an_integer);}
//function which expects an integer, and prints it
record a_record_containing_only_a_float_field {
float flt;
} record_name = new a_record_containing_only_a_float_field(53);
//This record's only field (a float) just got filled with an integer... not a big deal, right? should just be turned into 53.0, right?
function_who_wants_an_integer( record_name.flt );
return record_name;
The value of an_integer is: 53
Returned: record a_record_containing_only_a_float_field
flt => 53
int => float:
Code:
void function_who_wants_an_integer(int an_integer)
{ print("The value of an_integer is: " + an_integer);}
//function which expects an integer, and prints it
record a_record_containing_only_an_integer_field {
int i;
} record_name = new a_record_containing_only_an_integer_field(41.7);
//This record's only field (an integer) just got filled with a float... It'll be converted to 41, right?
function_who_wants_an_integer( record_name.i );
return record_name;
The value of an_integer is: 41
Returned: record a_record_containing_only_an_integer_field
i => 41.7
Code:
void function_who_wants_a_float(float a_float)
{ print("The value of a_float is: " + a_float);}
//function which expects a float, and prints it
record a_record_containing_only_an_integer_field {
int i;
} record_name = new a_record_containing_only_an_integer_field(41.7);
//This record's only field (an integer) just got filled with a float... It'll be converted to 41, right?
function_who_wants_a_float( record_name.i );
return record_name;
The value of a_float is: 41.7
Returned: record a_record_containing_only_an_integer_field
i => 41.7
Overall, all this would just be a "fun little fact" if it wasn't for memory-related worries: the values are either stored as they should with their datatype, or not.
What this means: if they are stored correctly, the maximum values just changed: for ints, the maximum is no longer 2 147 483 647.
If they are NOT, then this is an issue regarding memory. We're talking about OVERFLOW and UNDERFLOW: a float which became an int may be modified/may modify the previous thing stored in memory, because of the possibly added 16 bits of memory. For an int, it may impact/be impacted by the next, because of the possible 16 bits "added" to account for the decimal part.