1

クライアントとサーバーという2つの異なるMacで動作する2つの異なるアプリがあります。彼らは通信にHTTPを使用します。サーバーには、送信されたデータをカプセル化するplistファイルを公開するHTTPサーバーがあります。

例えば

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
      <key>sensorName</key>
      <string>external</string>
      <key>temperature</key>
      <real>8.8</real>
  </dict>
</plist>

クライアントはHTTPRequestを使用し、次のようにデータを収集します。

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        DDLogVerbose(@"URL Connection succeeded! Received %ld bytes of data",[testReceivedData length]);

        NSString *errorDescription = nil;
        NSPropertyListFormat format;
        NSDictionary *incomingPlist = [NSPropertyListSerialization propertyListFromData:testReceivedData
                                                                     mutabilityOption:NSPropertyListImmutable
                                                                               format:&format
                                                                     errorDescription:&errorDescription];

        if (errorDescription)
        {
            DDLogError(@"Error converting data from web into plist: %@", errorDescription);
            return;
        }

        DDLogVerbose(@"We got a plist from the server: %@", incomingPlist);

        NSString *sensorName;
        switch ([self currentCommandType]) {
            case MFRemoteCommandTypeSensorIndex:
                [self setSensorNames:[incomingPlist objectForKey:@"sensorNames"]];
                break;

            case MFRemoteCommandTypeTemperature:
                sensorName = [incomingPlist objectForKey:@"sensorName"];
                if (!sensorName)
                {
                    DDLogError(@"Could not get sensorname from temperature plist: %@", incomingPlist);
                    break;
                }
                [self didReceiveTemperatureReading:(NSNumber *)[incomingPlist objectForKey:@"temperature"] ForSensorName:sensorName];
                break;

            default:
                DDLogError(@"We should never get here.");
                break;
        }

        [self clearCurrentRequest];
    }

これまでのところ良好です....そしてデータは2つのアプリ間をうまく流れており、世界中ですべてが良好です。

ただし、原因がわからない場合があり、クライアントが温度値を誤って解釈することがあります。つまり、(上記のplistのように)温度NSNumberを8.8として解釈する代わりに、8.800000000000001または9.2を9.19999999999999として解釈します。

なぜそれがこれを行うのか誰かが知っていますか?奇妙なことに、それを行うときのパターンがないように見えます...

助けてくれてありがとう。

4

1 に答える 1

3

温度NSNumberを8.8として解釈すると、8.800000000000001として解釈され、9.2は9.19999999999999として解釈されます。

10進数は浮動小数点形式で正確に表現されていないことが多いため、数値を浮動小数点数として読み取っている場合は、非常に近いものとして表示される可能性が非常に高くなりますが、期待したものとまったく同じではありません。正確な表現が必要な場合は、NSDecimalNumberを確認してください。

ちなみに、10進数は、たまたま正確な10進数表現を持っている数値を除いて、2進数表現よりも正確ではないことを知っておく必要があります。たとえば、2進数表現も10進数表現も、1/3を正確に表すことはできません。

于 2013-01-31T20:01:27.797 に答える