IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Chroniqueur Actualités

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Mars 2013
    Messages
    8 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Mars 2013
    Messages : 8 382
    Points : 196 416
    Points
    196 416
    Par défaut Cryptomonnaies : le jeton IRON Titanium (TITAN) est passé de plus de 60 $ à pratiquement 0$ en quelques heures
    Cryptomonnaies : le jeton IRON Titanium (TITAN) est passé de plus de 60 $ à pratiquement 0 $ en quelques heures,
    un développeur accuse un bogue de programmation embarrassant

    IRON Titanium Token (TITAN) a subi une perte de près de 100 % en une seule journée, passant de son record historique de 64,19 USD le 16 juin à presque 0 USD le 17 juin. « Presque » signifie que le prix a atteint 0,000000049491 USD.

    Nom : titan.png
Affichages : 17464
Taille : 106,2 Ko

    Sur Twitter, Iron Finance a déclaré : « Chère communauté, veuillez retirer des liquidités de tous les pools. Nous partagerons un post-mortem dès que nous aurons une meilleure compréhension de ce bank run. La garantie USDC est disponible pour le rachat comme d’habitude ».

    Nom : iron.png
Affichages : 5402
Taille : 44,4 Ko

    Le « bank run », ou panique bancaire, est un phénomène dans lequel un grand nombre de clients d’une banque craignent qu’elle ne devienne insolvable et en retirent leurs dépôts le plus vite possible. Dans la cryptosphère, on l’appelle communément un « rug pull » (expression qui renvoie à l’idée de retirer de manière brusque le tapis/support sur lequel repose une personne, par exemple. Appliquée dans le contexte de DeFi, elle renvoie au retrait subit d’un pool de liquidité).

    Certains utilisateurs n’ont pas manqué de faire entendre leur déception comme Josh Cryp qui a déclaré : « Mes frais de scolarité ont disparu !!! J’avais 3 000 $ là-bas et il me reste 0,50 $. Que me reste-t-il à retirer ??!!! Ce n’est pas juste ! Celui qui a causé ça devrait être puni... Que vais-je faire maintenant ? »

    Nom : scolarite.png
Affichages : 5362
Taille : 8,9 Ko

    Ou encore cet autre qui a noté des limites dans le logiciel : « Vous n’avez pas fixé de limite de retrait, c’est ce qui l’a fait baisser, le prix de Titan est directement proportionnel à la quantité d’Iron miné ou à la demande d’Iron. Tandis que les gens commençaient à vendre Titan, les réserves d’IRON ont commencé à augmenter et le prix de Titan a chuté ».

    Nom : prix.png
Affichages : 5364
Taille : 13,8 Ko

    Que s’est-il passé ?

    Un stablecoin qu’est-ce que c’est ?

    Un stablecoin est un actif numérique qui réplique la valeur faciale d’une monnaie fiduciaire, souvent le dollar, comme le leader Tether (USDT) ou encore le DAI de MakerDAO. Point commun entre tous ces actifs : ils ont été créés pour protéger leurs porteurs des fluctuations spéculatives.

    Les stablecoins ont été imaginés comme un outil pour se prémunir contre la forte volatilité du marché des cryptomonnaies. Après une hausse impressionnante de l’ensemble des valeurs en 2017 suivie d’une chute brutale en 2018, certains investisseurs ont en effet éprouvé le besoin d’intégrer à leur portefeuille des cryptomonnaies plus stables dans une logique d’hedging (couverture du risque). Par ailleurs, les stablecoins pourraient également être un levier contribuant à l’adoption des applications décentralisées (Dapps) s’appuyant sur la technologie blockchain.

    Le cas du stablecoin IRON

    TITAN appartient à Iron Finance, un projet qui a commencé à faire le lien avec la chaîne de Polygon le 18 mai dans le but de tirer parti de l’efficacité de Polygon et de ses faibles frais de transaction.

    Le projet tentait de démarrer un stablecoin partiellement garanti connu sous le nom de IRON. Le stablecoin, à son tour, se compose du stablecoin de Circle et Coinbase, USDC, ainsi que TITAN, et était arrimé à 1 $. Les Stablecoins sont des cryptomonnaies dont la valeur est attachée à des actifs financiers tels que des matières premières ou des devises émises par le gouvernement dans le but de les maintenir stables.

    Dans le cas d’IRON, qui reçoit sa garantie de TITAN, les utilisateurs peuvent miner de nouveaux jetons stables via un mécanisme sur le réseau d’Iron Finance en verrouillant 25 % en TITAN et 75 % en USDC.

    En raison du fonctionnement de la «*tokenomics*» de ce projet DeFi particulier, lorsque de nouveaux jetons stables IRON sont minés, la demande de TITAN augmente, faisant grimper son prix. À l’inverse, lorsque le cours du TITAN chute fortement, comme ce fut le cas mercredi, l’arrimage devient instable.

    « Le prix de TITAN est passé à 65 $, puis est revenu à 60 $. Cela a poussé les baleines [grands investisseurs] à commencer à vendre », a déclaré Fred Schebesta, fondateur de Finder.com.au et investisseur d’Iron Finance. « Cela a ensuite conduit à un grand désarrimage de [IRON] ».

    Lorsque les gros investisseurs ont commencé à se décharger de leurs jetons TITAN, ils ont inondé le marché de jetons excédentaires, provoquant une panique bancaire.

    Tout cela suggère que les stablecoins algorithmiques, qui visent à stabiliser le prix en adaptant automatiquement l’offre à la demande, comportent leurs propres risques.

    La déclaration d’Iron Finance

    Iron Finance a déclaré à propos de la situation :

    « Nous n’avons jamais pensé que cela arriverait, mais c’est ce qui s’est passé. Nous venons de vivre la première panique bancaire crypto à grande échelle au monde.

    « Vers 10 h UTC le 16 juin-2021, nous avons remarqué que certaines baleines ont commencé à retirer des liquidités de IRON/USDC, puis ont vendu TITAN à IRON puis IRON à USDC directement aux pools de liquidités au lieu de racheter IRON, ce qui a entraîné une baisse du prix du IRON. TITAN est passé de 65 $ à 30 $ en 2 heures, qui a ensuite récupéré en 1 heure à 52 $ et IRON a complètement récupéré son ancrage (peg).

    « Le protocole et le code fonctionnaient comme d’habitude, et pendant que nous surveillions l’activité de la blockchain, nous pensions que c’était juste une autre correction avant la récupération. En fait, IRON a déjà été hors ancrage au moins une douzaine de fois dans toute son histoire, tandis que nos jetons d’actions (STEEL et TITAN) ont crashé beaucoup plus fort au cours des semaines précédentes. Les choses ne semblaient pas seulement éprouvées au combat, elles l’étaient. Les utilisateurs sont restés calmes et ont fait confiance au code, nous aussi.

    « Tout en travaillant sur le code fork de FRAX, nous avons étudié de près tous les projets qui ont fork FRAX et ne peuvent pas conserver leur ancrage à une date ultérieure. Pour cela, nous avons déjà mis en place de nombreuses améliorations comme notre mécanisme de doubles ratios de garanties, qui s’est déjà avéré efficace pour éviter les problèmes de out-peg qui se sont produits plusieurs fois dans des situations réelles auparavant.

    « Plus tard, vers 15 heures UTC, quelques gros détenteurs ont recommencé à vendre. Cette fois, après qu’ils aient commencé, de nombreux utilisateurs ont paniqué et ont commencé à racheter IRON et à vendre leur TITAN. En raison du fonctionnement de l’oracle TWAP (Time-weighted average price, une base pour les stratégies de trading) de 10 minutes, le prix au comptant du TITAN baisse encore plus par rapport au prix de rachat du TWAP. Cela a provoqué une boucle de rétroaction négative, car plus de TITAN ont été créés (à la suite de rachats de IRON) et le prix a continué à baisser. Une définition classique d’un événement irrationnel et paniqué également connu sous le nom de bank run. Au moment d’écrire ces lignes, l’offre TITAN est de 27*805 milliards.

    « À certains moments, le prix du TITAN est devenu si bas, proche de 0 en fait, ce qui a amené le contrat de rachat à annuler les transactions de rachat. Nous avons déjà mis en file d’attente le correctif pour cela, afin que les gens puissent à nouveau échanger à 17h UTC.

    « Ce que nous venons de vivre est la pire chose qui puisse arriver au protocole, une banque historique gérée dans l’espace cryptographique high-tech moderne. N’oubliez pas qu’Iron.finance est un stablecoin partiellement garanti, qui est similaire à la banque de réserve fractionnaire du monde moderne. Lorsque les gens paniquent et courent vers la banque pour retirer leur argent dans un court laps de temps, la banque peut s’effondrer et s’effondrera ».

    Un bogue de programmation embarrassant

    La situation aurait pu n’être qu’une simple fluctuation du marché et une opportunité d’arbitrage pour l’ensemble de cryptographie, sans l’effet de la variation drastique des prix sur le contrat intelligent d’IRON, le code exécuté sur la BinanceSmartChain qui régit les transactions.

    En termes simples, le contrat intelligent a échoué alors que le prix approchait de zéro.

    « Puisque le prix du TITAN est tombé à 0, le contrat ne permet pas de rachats », a expliqué Iron Finance, la firme à l’origine du stablecoin partiel IRON, dans un communiqué mercredi. « Nous devrons attendre 12 heures pour que le délai soit écoulé avant que les rachats par l’USDC ne soient à nouveau possibles ».

    Dans un billet publié jeudi sur Medium, une personne non identifiée a affirmé que la raison en était que le code de contrat intelligent IRON pour racheter (l’échanger contre une autre devise) le stablecoin pas si stable contient une erreur de limite :

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    require(_share_price > 0, “Invalid share price”);

    Voici le code qu’il a analysé :

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    // SPDX-License-Identifier: MIT
     
    pragma solidity 0.8.4;
     
    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
    import "@openzeppelin/contracts/access/Ownable.sol";
    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
    import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
     
    import "./interfaces/IShare.sol";
    import "./interfaces/IDollar.sol";
    import "./interfaces/ITreasury.sol";
    import "./interfaces/IOracle.sol";
    import "./interfaces/IPool.sol";
     
    contract Pool is Ownable, ReentrancyGuard, Initializable, IPool {
        using SafeERC20 for ERC20;
     
        /* ========== ADDRESSES ================ */
        address public oracle;
        address public collateral;
        address public dollar;
        address public treasury;
        address public share;
     
        /* ========== STATE VARIABLES ========== */
     
        mapping(address => uint256) public redeem_share_balances;
        mapping(address => uint256) public redeem_collateral_balances;
     
        uint256 public override unclaimed_pool_collateral;
        uint256 public unclaimed_pool_share;
     
        mapping(address => uint256) public last_redeemed;
     
        // Constants for various precisions
        uint256 private constant PRICE_PRECISION = 1e6;
        uint256 private constant COLLATERAL_RATIO_PRECISION = 1e6;
        uint256 private constant COLLATERAL_RATIO_MAX = 1e6;
     
        // Number of decimals needed to get to 18
        uint256 private missing_decimals;
     
        // Number of blocks to wait before being able to collectRedemption()
        uint256 public redemption_delay = 1;
     
        // AccessControl state variables
        bool public mint_paused = false;
        bool public redeem_paused = false;
     
        /* ========== MODIFIERS ========== */
     
        modifier onlyTreasury() {
            require(msg.sender == treasury, "!treasury");
            _;
        }
     
        /* ========== CONSTRUCTOR ========== */
     
        function initialize(
            address _dollar,
            address _share,
            address _collateral,
            address _treasury
        ) external initializer onlyOwner {
            dollar = _dollar;
            share = _share;
            collateral = _collateral;
            treasury = _treasury;
            missing_decimals = 18 - ERC20(_collateral).decimals();
        }
     
        /* ========== VIEWS ========== */
     
        function info()
            external
            view
            returns (
                uint256,
                uint256,
                uint256,
                bool,
                bool
            )
        {
            return (
                unclaimed_pool_collateral, // unclaimed amount of COLLATERAL
                unclaimed_pool_share, // unclaimed amount of SHARE
                getCollateralPrice(), // collateral price
                mint_paused,
                redeem_paused
            );
        }
     
        function collateralReserve() public view returns (address) {
            return ITreasury(treasury).collateralReserve();
        }
     
        function getCollateralPrice() public view override returns (uint256) {
            return IOracle(oracle).consult();
        }
     
        /* ========== PUBLIC FUNCTIONS ========== */
     
        function mint(
            uint256 _collateral_amount,
            uint256 _share_amount,
            uint256 _dollar_out_min
        ) external {
            require(mint_paused == false, "Minting is paused");
            (, uint256 _share_price, , uint256 _tcr, , , uint256 _minting_fee, ) = ITreasury(treasury).info();
            require(_share_price > 0, "Invalid share price");
            uint256 _price_collateral = getCollateralPrice();
            uint256 _total_dollar_value = 0;
            uint256 _required_share_amount = 0;
            if (_tcr > 0) {
                uint256 _collateral_value = ((_collateral_amount * (10**missing_decimals)) * _price_collateral) / PRICE_PRECISION;
                _total_dollar_value = (_collateral_value * COLLATERAL_RATIO_PRECISION) / _tcr;
                if (_tcr < COLLATERAL_RATIO_MAX) {
                    _required_share_amount = ((_total_dollar_value - _collateral_value) * PRICE_PRECISION) / _share_price;
                }
            } else {
                _total_dollar_value = (_share_amount * _share_price) / PRICE_PRECISION;
                _required_share_amount = _share_amount;
            }
            uint256 _actual_dollar_amount = _total_dollar_value - ((_total_dollar_value * _minting_fee) / PRICE_PRECISION);
            require(_dollar_out_min <= _actual_dollar_amount, "slippage");
     
            if (_required_share_amount > 0) {
                require(_required_share_amount <= _share_amount, "Not enough SHARE input");
                IShare(share).poolBurnFrom(msg.sender, _required_share_amount);
            }
            if (_collateral_amount > 0) {
                _transferCollateralToReserve(msg.sender, _collateral_amount);
            }
            IDollar(dollar).poolMint(msg.sender, _actual_dollar_amount);
        }
     
        function redeem(
            uint256 _dollar_amount,
            uint256 _share_out_min,
            uint256 _collateral_out_min
        ) external {
            require(redeem_paused == false, "Redeeming is paused");
            (, uint256 _share_price, , , uint256 _ecr, , , uint256 _redemption_fee) = ITreasury(treasury).info();
            uint256 _collateral_price = getCollateralPrice();
            require(_collateral_price > 0, "Invalid collateral price");
            require(_share_price > 0, "Invalid share price");
            uint256 _dollar_amount_post_fee = _dollar_amount - ((_dollar_amount * _redemption_fee) / PRICE_PRECISION);
            uint256 _collateral_output_amount = 0;
            uint256 _share_output_amount = 0;
     
            if (_ecr < COLLATERAL_RATIO_MAX) {
                uint256 _share_output_value = _dollar_amount_post_fee - ((_dollar_amount_post_fee * _ecr) / PRICE_PRECISION);
                _share_output_amount = (_share_output_value * PRICE_PRECISION) / _share_price;
            }
     
            if (_ecr > 0) {
                uint256 _collateral_output_value = ((_dollar_amount_post_fee * _ecr) / PRICE_PRECISION) / (10**missing_decimals);
                _collateral_output_amount = (_collateral_output_value * PRICE_PRECISION) / _collateral_price;
            }
     
            // Check if collateral balance meets and meet output expectation
            uint256 _totalCollateralBalance = ITreasury(treasury).globalCollateralBalance();
            require(_collateral_output_amount <= _totalCollateralBalance, "<collateralBalance");
            require(_collateral_out_min <= _collateral_output_amount && _share_out_min <= _share_output_amount, ">slippage");
     
            if (_collateral_output_amount > 0) {
                redeem_collateral_balances[msg.sender] = redeem_collateral_balances[msg.sender] + _collateral_output_amount;
                unclaimed_pool_collateral = unclaimed_pool_collateral + _collateral_output_amount;
            }
     
            if (_share_output_amount > 0) {
                redeem_share_balances[msg.sender] = redeem_share_balances[msg.sender] + _share_output_amount;
                unclaimed_pool_share = unclaimed_pool_share + _share_output_amount;
            }
     
            last_redeemed[msg.sender] = block.number;
     
            // Move all external functions to the end
            IDollar(dollar).poolBurnFrom(msg.sender, _dollar_amount);
            if (_share_output_amount > 0) {
                _mintShareToCollateralReserve(_share_output_amount);
            }
        }
     
        function collectRedemption() external {
            require((last_redeemed[msg.sender] + redemption_delay) <= block.number, "<redemption_delay");
     
            bool _send_share = false;
            bool _send_collateral = false;
            uint256 _share_amount;
            uint256 _collateral_amount;
     
            // Use Checks-Effects-Interactions pattern
            if (redeem_share_balances[msg.sender] > 0) {
                _share_amount = redeem_share_balances[msg.sender];
                redeem_share_balances[msg.sender] = 0;
                unclaimed_pool_share = unclaimed_pool_share - _share_amount;
                _send_share = true;
            }
     
            if (redeem_collateral_balances[msg.sender] > 0) {
                _collateral_amount = redeem_collateral_balances[msg.sender];
                redeem_collateral_balances[msg.sender] = 0;
                unclaimed_pool_collateral = unclaimed_pool_collateral - _collateral_amount;
                _send_collateral = true;
            }
     
            if (_send_share) {
                _requestTransferShare(msg.sender, _share_amount);
            }
     
            if (_send_collateral) {
                _requestTransferCollateral(msg.sender, _collateral_amount);
            }
        }
     
        /* ========== INTERNAL FUNCTIONS ========== */
     
        function _transferCollateralToReserve(address _sender, uint256 _amount) internal {
            address _reserve = collateralReserve();
            require(_reserve != address(0), "Invalid reserve address");
            ERC20(collateral).safeTransferFrom(_sender, _reserve, _amount);
        }
     
        function _mintShareToCollateralReserve(uint256 _amount) internal {
            address _reserve = collateralReserve();
            require(_reserve != address(0), "Invalid reserve address");
            IShare(share).poolMint(_reserve, _amount);
        }
     
        function _requestTransferCollateral(address _receiver, uint256 _amount) internal {
            ITreasury(treasury).requestTransfer(collateral, _receiver, _amount);
        }
     
        function _requestTransferShare(address _receiver, uint256 _amount) internal {
            ITreasury(treasury).requestTransfer(share, _receiver, _amount);
        }
     
        /* ========== RESTRICTED FUNCTIONS ========== */
     
        function toggleMinting() external onlyOwner {
            mint_paused = !mint_paused;
        }
     
        function toggleRedeeming() external onlyOwner {
            redeem_paused = !redeem_paused;
        }
     
        function setOracle(address _oracle) external onlyOwner {
            require(_oracle != address(0), "Invalid address");
            oracle = _oracle;
        }
     
        function setRedemptionDelay(uint256 _redemption_delay) external onlyOwner {
            redemption_delay = _redemption_delay;
        }
     
        function setTreasury(address _treasury) external onlyOwner {
            require(_treasury != address(0), "Invalid address");
            treasury = _treasury;
            emit TreasuryChanged(_treasury);
        }
     
        // EVENTS
        event TreasuryChanged(address indexed newTreasury);
    }

    Si c’est correct, l’utilisation de l’opérateur ">" (supérieur à) plutôt que ">=" (supérieur ou égal à) signifierait qu’une valeur TITAN évaluée comme zéro (qui dépend de la précision numérique du calcul) serait être considéré comme invalide et serait refusé pour le rachat.

    Quoi qu’il en soit, cette affirmation n’a pas été confirmée par Iron Finance, et ce dernier s’est refusé à tout commentaire concernant cette éventualité. Cependant, la propre description de l’incident par Iron Finance décrit un scénario cohérent avec ce qui a été proposé par l’auteur non identifié de Medium :

    « À certains moments, le prix du TITAN est devenu si bas, proche de 0 en fait, ce qui a amené le contrat de rachat à annuler les transactions de rachat », a déclaré Iron Finance dans son rapport d’incident jeudi (vers 16 heures UTC). « Nous avons déjà mis en file d’attente le correctif pour cela, afin que les gens puissent à nouveau échanger à 17h UTC ».

    Sources : communiqué Iron Finance, tweets Iron Finance (1, 2), en savoir plus sur IRON, GitHub (code contrats), individu non identifié
    Contribuez au club : Corrections, suggestions, critiques, ... : Contactez le service news et Rédigez des actualités

  2. #2
    Membre expert
    Profil pro
    programmeur du dimanche
    Inscrit en
    Novembre 2003
    Messages
    777
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : programmeur du dimanche
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2003
    Messages : 777
    Points : 3 339
    Points
    3 339
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    5.551115123125783e-17
    ** Process exited - Return Code: 0 **
    C'est pas une bonne pratique universelle en finance d'utiliser un langage ou une lib de calcul flottant à haute précision et de tester les problèmes d'arrondi ?

  3. #3
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 545
    Points : 1 424
    Points
    1 424
    Par défaut
    dans le même genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include <stdio.h>
    int main(){
        printf("%d",(1LL<<53)+1.0 == (1LL<<53));
        return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    1
    
    ...Program finished with exit code 0

  4. #4
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 932
    Points : 1 267
    Points
    1 267
    Par défaut
    C'est bizarre... l'usage de nombre entiers (avec une unité valant une fraction de centimes) ne suffit-elle pas à éviter ce genre de problèmes d'instabilité numérique ?

    Les flotants c'est pratique mais vicieux...

    Par exemple dans mes applications type CAO, toutes mes coordonnées (X, Y, et Z pour la 3D) sont des nombres entiers.

    une unité équivaut à un micron ce qui est suffisant étant donné la précision des machines pilotées (bien sûr, on peut aller plus bas)

    En effet, avec des nombres à virgule flottante, la précision absolue dépend de la valeur de la coordonnées (meilleure quand la coordonnée a une valeur faible) et du coup à chaque translation, la valeur des coordonnées change, donc à chaque translation on déforme un peu ses pièces
    De même, des formes identiques mais à des coordonnées différentes ne sont pas identiques.
    Avec certains algorithmes sensibles (collision, fusion de polygones) cela engendre une pagaille monstrueuse

    Je trouve que c'est un point qui n'est pas suffisamment enseigné en cours de programmation, et il est à l'origine de bugs très difficiles à résoudre.
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  5. #5
    Membre actif
    Avatar de Aiigl59
    Homme Profil pro
    Freelance
    Inscrit en
    Janvier 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 88
    Points : 257
    Points
    257
    Billets dans le blog
    1
    Par défaut La valeur du virtuel...
    Il est évident que ce qui ne vaut rien au départ ne vaudra toujours rien à l'arrivée, quelque soient les spéculations appliquées dessus...
    Il n'est pas donné aux hommes ni à ses machines de créer "ex-nihilo", et cela se vérifiera toujours...
    Les perdants dans l'histoire seront ceux qui sont attiré par ces "miroirs aux alouettes", l'histoire se répète, rien de nouveau sous le soleil...
    Salutations à toutes et à tous !

  6. #6
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 295
    Points
    7 295
    Par défaut
    Citation Envoyé par electroremy Voir le message
    C'est bizarre... l'usage de nombre entiers (avec une unité valant une fraction de centimes) ne suffit-elle pas à éviter ce genre de problèmes d'instabilité numérique ?

    Les flotants c'est pratique mais vicieux...

    Par exemple dans mes applications type CAO, toutes mes coordonnées (X, Y, et Z pour la 3D) sont des nombres entiers.

    une unité équivaut à un micron ce qui est suffisant étant donné la précision des machines pilotées (bien sûr, on peut aller plus bas)

    En effet, avec des nombres à virgule flottante, la précision absolue dépend de la valeur de la coordonnées (meilleure quand la coordonnée a une valeur faible) et du coup à chaque translation, la valeur des coordonnées change, donc à chaque translation on déforme un peu ses pièces
    De même, des formes identiques mais à des coordonnées différentes ne sont pas identiques.
    Avec certains algorithmes sensibles (collision, fusion de polygones) cela engendre une pagaille monstrueuse

    Je trouve que c'est un point qui n'est pas suffisamment enseigné en cours de programmation, et il est à l'origine de bugs très difficiles à résoudre.
    C'est effectivement une astuce largement sous étudiée.
    Privilégier les entier a la place des doubles reste une manière d'optimiser son code rapidement, et de le simplifier aussi souvent

  7. #7
    Membre confirmé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 329
    Points : 606
    Points
    606
    Par défaut
    Citation Envoyé par pmithrandir Voir le message
    C'est effectivement une astuce largement sous étudiée.
    Privilégier les entier a la place des doubles reste une manière d'optimiser son code rapidement, et de le simplifier aussi souvent
    Le langage Forth (https://fr.wikipedia.org/wiki/Forth_(langage)), conçu jadis pour faire des calculs astronomique de haute précision ne manipulait au départ que des entiers.
    GraceGTK: a plotting tool at https://sourceforge.net/projects/gracegtk

Discussions similaires

  1. La RAM de mon PC est passé de 512Mo à 256Mo ???
    Par elitost dans le forum Composants
    Réponses: 8
    Dernier message: 14/02/2006, 23h00
  2. comment savoir par quelle page est passé un visiteur
    Par emilie_per dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2006, 12h11
  3. [POO] Désactiver un objet dont le nom est passé en parametre
    Par JavaEli dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 12/07/2005, 09h47
  4. [VC++ .NET] mais où est passée SignedXML ???
    Par benoitB dans le forum MFC
    Réponses: 4
    Dernier message: 30/04/2004, 09h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo