Wrox Programmer Forums
|
BOOK: Beginning PHP4/PHP 5 ISBN: 978-0-7645-4364-7; v5 ISBN: 978-0-7645-5783-5
This is the forum to discuss the Wrox book Beginning PHP4 by Wankyu Choi, Allan Kent, Chris Lea, Ganesh Prasad, Chris Ullman; ISBN: 9780764543647
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Beginning PHP4/PHP 5 ISBN: 978-0-7645-4364-7; v5 ISBN: 978-0-7645-5783-5 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old October 30th, 2003, 04:53 PM
richard.york's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
Default

No problem at all!

Quote:
quote:
It stumped me at first. I am just learning PHP, so I thought it was my own doing. This kind of thing does concern me, however, for future programs I build. If these conditions do not work, how can it be trusted?
It stumped me too!
This is a fluke. I've never encountered anything that would produce this kind of result and I've been working with PHP for a good while now. I'm going to wait and see if Nik has anything to say about it and then I'm thinking of submitting a bug report to the PHP group. Nik being one of the most experienced among us might have some insight. The value shouldn't need to be rounded, it's not a decimal, if it were it should output as one. To me it seems like inserting a ceil() [which rounds up] is overkill. It doesn't make sense but I'm sure that there is a logical explaination for it... could be that it is a bug in PHP.

I wouldn't worry about your conditionals failing needlessly, I've been developing complex PHP applications for two years and this is the first time I've seen one fail where the logic and syntax were all in tact.

: )
Rich

:::::::::::::::::::::::::::::::::
Smiling Souls
http://www.smilingsouls.net
:::::::::::::::::::::::::::::::::
 
Old October 30th, 2003, 10:00 PM
richard.york's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
Default

I went ahead and submitted a bug report.

I thought, what the hell, we'll see what they have to say about it.
http://bugs.php.net/bug.php?id=26046

Well they basically blew us off folks! Apparently my example code was *too long*. I got an auto-reply stating the bug was bogus. Now why would I expect to actually have a human look at the code???

: )
Rich


:::::::::::::::::::::::::::::::::
Smiling Souls
http://www.smilingsouls.net
:::::::::::::::::::::::::::::::::
 
Old November 1st, 2003, 03:26 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Well, it's kind of a bug, but not really... the problem is due to making comparisons using variables of different data types. All form data is submitted as a string, so if you're going to perform any sort of mathematical comparisons on the data, your string needs to be converted to the appropriate type.

Since floating point numbers use the same number of bytes as a regular integer, but can store a much wider range of numbers, you realize that a lot of precision is lost due to how the number is encoded. With integers, every bit in the number represents some part of that integer. With floats, some bits are used to store a base number, and others are used to store an exponent.

For example, it might not be possible to store the actual value of 10,000 as a float -- the number being stored might actually be 9999.99999, which is less than the integer 10000, but is still displayed as the rounded-up value.


What seems to be happening here is that the loan allowance is being calculated as a floating point number which might not be exactly 10000, but is pretty damn close.

Since the code is suggesting that the loan asked for ($_POST['Loan']) is greater than the loan allowance, you should be able to calculate a non-zero difference between the two:

$diff = ($_POST['loan'] - $LoanAllowance);
var_dump($diff);

I get: 1.8189894035459E-12

That's a really small number, but it's still there. The loan being asked for is about 0.000000000002 more than the loan allowed.


To ensure that all your mathematical comparisons are performed properly, you should always make sure that you're using the same data type and, if possible, round both numbers using the same rules. For example, using currency naturally lends itself to rounding to two decimal places. Using ceil() would mean that a loan of 10000 would be approved for someone who only qualifies for 9999.00001.


$loan = round((float)$_POST['Loan'], 2);
$LoanAllowance = round($LoanAllowance, 2);

Note that I explicitly cast the string value $_POST['loan'] to a float before rounding. I don't think this is necessary, but it adds clarity.


You'll find that the code works as expected after performing the proper casting and rounding operations.


Take care,

Nik
http://www.bigaction.org/
 
Old November 2nd, 2003, 02:40 AM
richard.york's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
Default

Thanks Nik,
I knew you were up to the challenge! I had some suspicions that the Loan Allowance amount was less than a whole number, and the way that you explained things made why that appeared as so crystal clear. It never occured to me to attempt to find the difference between the two. And it still drives me mad that the number printed out as a whole number when it was in fact a decimal!

I appreciate the insight!

For future reference for the rest of you:
Nik mentioned type-casting a bit and I thought I would elaborate a little on how to do that.

An integer, or floating integer may be cast explicitly in PHP using two methods:

One is the function:
bool settype(mixed variable, string type)
http://us2.php.net/settype

This will take a variable and cast it to whatever type is specified in the second argument.

$foo = "abracadabra1"; # (string)
settype($foo, "integer"); # $foo now contains a value of '1' and has been cast an integer

And the other method is through type-casting which is used when a variable is set. http://us2.php.net/manual/en/languag...es.typecasting

$foo = (int) 1;

PHP automatically determines what context you intend data to be used. For instance, if you set the variable $foo above to "abracadabra1", and used that string in a mathematical context PHP already knows that you only want to use the '1' portion of the string. However it is good practice to use type-casting, which many other languages require, and if you intend to learn other languages like, C, is simply good preparation. And IMO in PHP its just another small thing that can be done to enhance readability and understanding. Not required, but a nifty thing to know about.

: )
Rich

:::::::::::::::::::::::::::::::::
Smiling Souls
http://www.smilingsouls.net
:::::::::::::::::::::::::::::::::
 
Old November 3rd, 2003, 02:15 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I'm glad to be of help.

There's a couple problems in your post that I'd like to clarify:

Quote:
quote:Originally posted by quesadilla5
PHP automatically determines what context you intend data to be used. For instance, if you set the variable $foo above to "abracadabra1", and used that string in a mathematical context PHP already knows that you only want to use the '1' portion of the string.
This is actually incorrect. PHP parses strings from left-to-right when performing type conversions. If you have the string "1,000" PHP will convert that string to the integer 1. The comma is not a digit or decimal character and therefore terminates the conversion.

In your example, "abracadabra1", PHP converts the string as 0 (zero) because the first character is NOT a valid numerical character (digit, decimal, or minus-sign).


Quote:
quote:Originally posted by quesadilla5
However it is good practice to use type-casting, which many other languages require, and if you intend to learn other languages like, C, is simply good preparation.
Many compiled languages (i.e. non-interpreted, not a scripting language) don't let you cast between string and numerical values. These conversions require you to either write your own function to perform the conversion or to call a function in some library. In C, the function to convert a string to an integer is atoi(). (The name stands for "ascii to integer").

You can cast between integers, booleans, and floating point numbers, and you have to be aware of the loss of precision in the cast. For example, a boolean false is cast as a numerical zero, so what should a boolean true be? Any non-zero number is cast as boolean true when going from number -> boolean, so you can't just assume that going from boolean -> number should result in the integer 1 (though it usually does).



Take care,

Nik
http://www.bigaction.org/
 
Old November 3rd, 2003, 02:27 PM
richard.york's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
Default

Quote:
quote:
In your example, "abracadabra1", PHP converts the string as 0 (zero) because the first character is NOT a valid numerical character (digit, decimal, or minus-sign).
Thanks for clarifiying that. That assumption could have become a nusiance.

I got the relation of type-casting in PHP to C from the manual page which said:

Quote:
quote:
Type casting in PHP works much as it does in C: the name of the desired type is written in parentheses before the variable which is to be cast.
So purely from the standpoint of casting a variable when set, that's true, right? I've written but one program in C, the infamous hello,world! so I don't know jack about it really.

: )
Rich

:::::::::::::::::::::::::::::::::
Smiling Souls
http://www.smilingsouls.net
:::::::::::::::::::::::::::::::::
 
Old November 3rd, 2003, 02:31 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Oh. My. God.

Okay, am I the only one that sees how lame this is?

  $AgeAllowance = ($Age/10 - ($Age%10)/10)-1;


PHP's division operator, /, always returns a floating point number, even when both operands are integers. Therefore, 5/1 is 5.0, and 5/2 is 2.5.

The result of the modulo division part of the equation, then, simply exists to subtract the decimal part of the numerical division part of the equation. For example, with the age 23, the division and modulo parts are 2.3 and 0.3. With age 35, you have 3.5 and 0.5. These subtractions simply leave you with the digit in the 10's place of your age (zero for ages 0 - 9).

To put it plainly -- the number they're trying to come up with is an integer value that equals the 10's part of your age - 1. Here's a chart:

Code:
   Age Range | Age Allowance
  -----------+--------------- 
    0 -  9   |     -1
   10 - 19   |      0
   20 - 29   |      1
   30 - 39   |      2
          etc...
The division of a decimal number by it's decimal part is just "rounding down". There's a built-in function to do that: floor().


This could've probably been a lot more readable using:

$AgeAllowance = floor($Age / 10) - 1;


Okay, rant over.


Take care,

Nik
http://www.bigaction.org/
 
Old November 3rd, 2003, 02:45 PM
Registered User
 
Join Date: Oct 2003
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via AIM to brandonsaxe
Default

Thank you, Nik for all the information.

This brings a question up for me.

With such lame code that is in this book, should I continue to use it to learn PHP? Or am I just learning poor practices?

Any books you recommend?
 
Old November 3rd, 2003, 02:46 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

The manual is just saying is that the syntax for type casting is the same as it is in C; that is, your desired type is in parenthesis before the value being cast.

So in C:

float my_float = 5.2;
int my_int = (int)my_float;

in PHP:
$my_float = 5.2;
$my_int = (float)$my_float;


Take care,

Nik
http://www.bigaction.org/
 
Old November 3rd, 2003, 03:18 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by brandonsaxe
 Thank you, Nik for all the information.

This brings a question up for me.

With such lame code that is in this book, should I continue to use it to learn PHP? Or am I just learning poor practices?

Any books you recommend?
Well, continue to use the book since you've already got it and most of the stuff works... but don't limit yourself to the book for your sources of knowledge. Use this forum. Use PHPBuilder.com and other tutorial sites.

PHP is a fairly easy-to-use language, and as such, it's user base consists largely of new programmers with little or no formal training in software engineering concepts and theories. It's these same programmers who have all the built-in functions of PHP memorized that write PHP books without putting much emphasis on abstract application design concepts.

For interesting reading:
  http://philip.greenspun.com/wtr/dead-trees/story.html
  http://www.ramblingrose.com/ComputerBooks.htm
  http://www.google.com/search?&q=why+computer+books+suck



Take care,

Nik
http://www.bigaction.org/





Similar Threads
Thread Thread Starter Forum Replies Last Post
Strange Behavior With Anchor in XSLT kwilliams XSLT 6 July 21st, 2005 01:52 PM
STRANGE behavior..SQL Help skotman Classic ASP Databases 7 June 6th, 2004 02:55 PM
Strange behavior of DateTimePicker? wwz VS.NET 2002/2003 0 February 19th, 2004 06:56 AM
Please help with strange file download behavior! glwatson Classic ASP Basics 0 September 10th, 2003 07:57 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.