I am trying to add the value of my textfield plus the value of my label and place it in another label.
-(IBAction)finalTipTotalSelection:(id)sender
{
NSString *billFinalAmount = [billAmountTextField text];
float billFinalAmountFloat = [billFinalAmount floatValue];
NSString *tipTotalAmount = [resultLabel text];
float tipTotalAmountFloat = [tipTotalAmount floatValue];
float finalAmountShow = billFinalAmountFloat + tipTotalAmountFloat;
NSString *finalResult = [NSString stringWithFormat:#"$ %0.2f", finalAmountShow];
[finalTotalLabel setText:finalResult];
}
I am creating floatValues for the Strings and then in a float adding the other floatValues together, and finally displaying it in a label. The only issues is when I run this code the finalTotalLabel (shows the final amount) only shows the value of the billAmountTextField. So if the billAmountTextField = 187.82 and the tipTotalAmount was 10, the finalTotalLabel would show 187.82 (not 197.82). I cant seem to find my mistake. Thanks for your help!
It is caused by the tipTotalAmount having the $ character at the beginning of the string. The resulting float value for the tip amount will be 0.0 because:
floatValue... returns 0.0 if the receiver doesn’t begin with a valid
text representation of a floating-point number.
You can take a look at the class reference of NSString for the explanation of the return value of floatValue.
Try to filter out the non decimal and dot character first from the NSString instance before passing the message floatValue to it, for example:
NSMutableCharacterSet *_alnum = [NSMutableCharacterSet characterSetWithCharactersInString:#"."];
[_alnum formUnionWithCharacterSet:[NSCharacterSet decimalDigitCharacterSet]];
NSString *newTipTotalAmount = [[tipTotalAmount componentsSeparatedByCharactersInSet:
[_alnum invertedSet]]
componentsJoinedByString:#""];
float tipTotalAmountFloat = [newTipTotalAmount floatValue];
Here the newTipTotalAmount will be "39.19" compared to the tipTotalAmount which is "$ 39.19" and passing the floatValue message to newTipTotalAmount will give you the correct float value.
Related
Firstly, I created some text values
Text gamecon1 = Text('1v1 Box Fight');
Text gamecon1duo = Text('1v1 Duos');
Text gamecon2 = Text('2v2 Box Fight');
Text gamecon2sq = Text('2v2 Squads');
Text gamecon3 = Text('3v3 Box Fight');
Text gamecon4 = Text('4v4 Box Fight');
Then i queried a document field from firestore and wrote a conditional statement
Text((() {
if (tourneyDetails['tourneyprizes'] ==
gamecon1) {
return multiplier = 8;
} else if (tourneyDetails[
'tourneyprizes'] ==
gamecon1duo) {
return multiplier = 5;
String calculator = (int.parse(
tourneyDetails[
'tourneycost']) *
multiplier)
.toString();
String calculatordivide =
(double.parse(calculator) / 100.0)
.toString();
String calculatorpercentage =
(double.parse(calculatordivide) *
20)
.toString();
String calculatorfinal =
(double.parse(calculator) -
double.parse(
calculatorpercentage))
.toString();
return calculatorfinal;
What i am trying to accomplish is, if the document field is equal to one the text values, then it should run the calculation and return the value.
but this doesn't work.
After some troubleshooting, i realised that even when the text value is the same as the document field queried, flutter still doesn't recognise it.
If you need more context feel free to comment. Thanks
Without knowing what the type definition of tourneyDetails is I cannot be sure but I suspect that you are trying to compare a String (in tourneyDetails) with a Text widget. If so, they will never equate. You should be defining your strings as constants eg. const gamecon1 = '1v1 Box Fight'; then the comparison should equate.
Text() is a widget. You want to compare Strings.
if (tourneyDetails['tourneyprizes'] == gamecon1.data)
or
define String gamecon1 = 'gamecon1' and tourneyDetails must also be an array of Strings.
This is the line of code in question:
bks.quantity = [NSNumber numberWithInteger: [[arrayOfSplitStrings[i] objectAtIndex:[[sd.dictionaryOfUserIndexes objectForKey: #"29"] intValue]] intValue]-1];
sd.dictionaryOfUserIndexes objectForKey: #"29" contains a string (representing a quantity) that has to be converted to NSNumber. When the statement is executed with a valid string quantity (0-10) it always returns -1, when it is supposed to return the NSNumber for the value.
What am I doing wrong?
This is not a "straight forward" answer (since the solution is just a silly one), it's more a suggestion on work methods, that's why I post an answer.
It's not always good to put it various lines in a single line.
Especially when in your case you encounter an issue. It's better to split each command, one by one, and to debug, check the value of each ones.
In your case:
bks.quantity = [NSNumber numberWithInteger: [[arrayOfSplitStrings[i] objectAtIndex:[[sd.dictionaryOfUserIndexes objectForKey: #"29"] intValue]] intValue]-1];
==>
NSInteger userOfIndexes = [[sd.dictionaryOfUserIndexes objectForKey: #"29"] intValue];
NSLog(#"userOfIndexes: %d", userOfIndexes);
NSInteger n = [arrayOfSplitStrings[i] objectAtIndex:userOfIndexes] intValue];
NSLog(#"n: %d", n);
bks.quantity = [NSNumberWithInteger:n-1];
I added NSLog(), but the values could be check with breakpoints and debugger. I could have also add a check on arrayOfSplitStrings with
NSArray *splitStrings = arrayOfSplitString[i];
NSLog(#"splitStrings: %#", splitStrings);
and replace n with:
NSInteger n = [splitStrings objectAtIndex:userOfIndexes] intValue];
That way, you would have check that apparently (according to your comment), your issue was were to put the "-1.
NSInteger n = [[arrayOfSplitStrings[i] objectAtIndex: userIndex-1] intValue];
var clientString = "{\"max\":1214.704958677686}";
JObject o = JObject.Parse(clientString);
var jsonString = o.ToString();
contents of jsonString:
{
"max": 1214.7049586776859
}
this is both in visualizing the object and in doing ToString(). Note that the 686 has mysteriously been expanded to 6859 (precision added). This is a problem for us because the numbers are not exactly the same, and a hash function over the json later does not match.
#Ilija Dimov is correct--JSON.NET parses JSON floats as doubles by default. If you still want to use JObject instead of creating a full blown POCO for deserialization, you can use a JsonTextReader and set the FloatParseHandling option:
var reader = new JsonTextReader(new StringReader(clientString));
reader.FloatParseHandling = FloatParseHandling.Decimal;
JObject obj = JObject.Load(reader);
Console.WriteLine(obj["max"].Value<decimal>()); // 1214.704958677686
The reason your value is changed is because of the nature of floating point numbers in .NET. The JObject.Parse(clientString) method at some point executes the following line:
double d;
double.TryParse("1214.704958677686", NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out d);
where d represents the number that you get in the JObject.
As d is of type double and double is floating point number, you didn't get the value you expect. Read more about Binary floating point and .NET.
There is an option in JSON.NET for parsing floating point numbers as decimals and get the precision you need, but to do that you need to create custom class that matches your json string and deserialize the json. Something like this:
public class MyClass
{
[JsonProperty("max")]
public decimal Max { get; set; }
}
var obj = JsonConvert.DeserializeObject<MyClass>(clientString, new JsonSerializerSettings
{
FloatParseHandling = FloatParseHandling.Decimal
});
By using this code sample, the value of max property won't be changed.
You can experiment this behaviour just by parsing to float, double and decimal:
Assert.AreEqual(1214.705f,float.Parse("1214.704958677686"));
Assert.AreEqual(1214.7049586776859, double.Parse("1214.704958677686"));
Assert.AreEqual(1214.704958677686, decimal.Parse("1214.704958677686"));
So json.net is using double as an intermediate type. You can change this by setting FloatParseHandling option.
I got a question for anyone with a spare moment and an answer...
I need to change an NSString value to input into the AVAudioPlayer start offset
eg. player.currentTime = 0; I want to change the '0' to a readable value or an NSString to a numeral value.....
NSString has a integerValue function. You can also create an NSString using it's format class function and pass it a format string like this: "%d" and then your player.currentTime.
int timeInput = [[textField text] integerValue];
label.text = [NSString stringWithFormat:#"%d", timeInput];
Could someone explain why the FLEX 4.5 XMLDecoder does this to my XML-data?
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>08.00</xmltag> );
// object = "08.00"
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>11.00</xmltag> );
// Object = "11" (HEY! Where did my '.00' part of the string go?)
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>11.30</xmltag> );
// Object = "11.3" (HEY! Where did my '0' part of the string go?)
The Flex deserializer also gave me issues with this. It may be interpreting them as Number objects and thus they will return short representations when toString() is called.
Try using .toFixed(2) whenever you need to print a value such as 11.00
var $object:Object = decoder.decode( <xmltag>11.00</xmltag> );
trace($object); //11
trace($object.toFixed(2)); //11.00
So, to the answer the original question of why this is happening:
In the source code for SimpleXMLDecoder (which I'm guessing has similar functionality to XMLDecoder), there's a comment in the function simpleType():
//return the value as a string, a boolean or a number.
//numbers that start with 0 are left as strings
//bForceObject removed since we'll take care of converting to a String or Number object later
numbers that start with 0 are left as strings - I guess they thought of phone numbers but not decimals.
Also, because of some hacky implicit casting, you actually have three different types -
"0.800" : String
11 : int
11.3: Number